recv bringt nichts
-
Soooo, nun zum Anfang.
Ich habe versucht, von einem pop3 server meine Nachrichten abzurufen. Das hat mit netcat wunderbar geklappt. Jetzt habe ich versucht, das automatisiert zu machen, doch recv blockiert bzw. es kommt nichts an. Jetz zu meiner Frage: WARUM kommt nichts an. Anbei meine Sources:main.c
#include "socketprx.h" #include <string.h> int main(void) { socket_t sock; char *sendbuf = (char *)malloc (1024); char *recvbuf = (char *)malloc (1024); sock = create_socket(AF_INET, SOCK_STREAM, 0); atexit(cleanup); connect_socket(&sock, "mx.freenet.de", 110); TCP_recv(&sock, recvbuf, 1023); printf("%s",recvbuf); // memset(recvbuf, 0, 1023); strcpy(sendbuf, "USER s000ur@freenet.de\r\n\r\n"); TCP_send(&sock, sendbuf, sizeof(sendbuf)); TCP_recv(&sock, recvbuf, sizeof(recvbuf)); printf("%s",recvbuf); printf("blatest\n"); close_socket (&sock); return EXIT_SUCCESS; }
socketprx.h
/* socketprx.h für Linux/UNIX */ #ifndef SOCKETPRX_H_ #define SOCKETPRX_H_ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <arpa/inet.h> #include <unistd.h> /* ein eigener primitver Datentyp für den Socket-Deskriptor */ #define socket_t int /* Funktionsprototypen */ void error_exit(char *error_message); int create_socket( int af, int type, int protocol ); void bind_socket(socket_t *sock, unsigned long adress, unsigned short port); void listen_socket( socket_t *sock ); void accept_socket( socket_t *new_socket, socket_t *socket ); void connect_socket(socket_t *sock, char *serv_addr, unsigned short port); void TCP_send( socket_t *sock, char *data, size_t size); void TCP_recv( socket_t *sock, char *data, size_t size); void close_socket( socket_t *sock ); void cleanup(void); #endif
socketlayer.c
/* socketlayer.c - für Linux/UNIX */ #include "socketprx.h" /* Die Funktion gibt aufgetretene Fehler aus und * beendet die Anwendung. */ void error_exit(char *error_message) { fprintf(stderr, "%s: %s\n", error_message, strerror(errno)); exit(EXIT_FAILURE); } int create_socket( int af, int type, int protocol ) { socket_t sock; const int y = 1; /* Erzeuge das Socket. */ sock = socket(af, type, protocol); if (sock < 0) error_exit("Fehler beim Anlegen eines Sockets"); /* Mehr dazu siehe Anmerkung am Ende des Listings ... */ setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int)); return sock; } /* Erzeugt die Bindung an die Serveradresse, * (genauer gesagt an einen bestimmten Port). */ void bind_socket(socket_t *sock, unsigned long adress, unsigned short port) { struct sockaddr_in server; memset( &server, 0, sizeof (server)); server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(adress); server.sin_port = htons(port); if (bind(*sock, (struct sockaddr*)&server,sizeof(server)) < 0) error_exit("Kann das Socket nicht \"binden\""); } /* Teile dem Socket mit, dass Verbindungswünsche * von Clients entgegengenommen werden. */ void listen_socket( socket_t *sock ) { if(listen(*sock, 5) == -1 ) error_exit("Fehler bei listen"); } /* Bearbeite die Verbindungswünsche von Clients. * Der Aufruf von accept() blockiert so lange, * bis ein Client Verbindung aufnimmt. */ void accept_socket( socket_t *socket, socket_t *new_socket ){ struct sockaddr_in client; unsigned int len; len = sizeof(client); *new_socket=accept(*socket,(struct sockaddr *)&client, &len); if (*new_socket == -1) error_exit("Fehler bei accept"); } /* Baut die Verbindung zum Server auf. */ void connect_socket(socket_t *sock, char *serv_addr, unsigned short port) { struct sockaddr_in server; struct hostent *host_info; unsigned long addr; memset( &server, 0, sizeof (server)); if ((addr = inet_addr( serv_addr )) != INADDR_NONE) { /* argv[1] ist eine numerische IP-Adresse */ memcpy( (char *)&server.sin_addr, &addr, sizeof(addr)); } else { /* Für den Fall der Fälle: Wandle den * Servernamen bspw. "localhost" in eine IP-Adresse um. */ host_info = gethostbyname( serv_addr ); if (NULL == host_info) error_exit("Unbekannter Server"); memcpy( (char *)&server.sin_addr, host_info->h_addr, host_info->h_length); } server.sin_family = AF_INET; server.sin_port = htons( port ); /* Baue die Verbindung zum Server auf. */ if (connect( *sock, (struct sockaddr *)&server, sizeof( server)) < 0) error_exit( "Kann keine Verbindung zum Server herstellen"); } /* Daten versenden via TCP */ void TCP_send( socket_t *sock, char *data, size_t size) { if(send( *sock, data, size, 0) == -1 ) error_exit("Fehler bei send()"); } /* Daten empfangen via TCP */ void TCP_recv( socket_t *sock, char *data, size_t size) { unsigned int len; len = recv (*sock, data, size, 0); if( len > 0 || len != -1 ) data[len] = '\0'; else error_exit("Fehler bei recv()"); } /* Socket schließen */ void close_socket( socket_t *sock ){ close(*sock); } /* Unter Linux/UNIX ist nichts zu tun ... */ void cleanup(void){ printf("Aufraeumarbeiten erledigt ...\n"); return; }
Der Debugger sagt, er hängt beim recv in der Datei socketlayer.c in der Funktion TCP_recv.
Doch warum? Normalerweise müsste doch kommen:
+OK user okWoran liegt es? Ich bin echt ratlos...
Edit: Hat sich erledigt, sizeof(malloced) geht nicht.
Noch eine Frage habe ich vorerst:
strcpy(sendbuf, "USER s000ur@freenet.de\r\n\r\n");
TCP_send(&sock, sendbuf, 1023);
geht jetzt. Aber wenn ich den String direkt einfüge, also ohne strcpy nicht:
TCP_send(&sock, "USER s000ur@freenet.de\r\n\r\n", 1023);
Das zweite wäre nämlich nicht so aufwendig, wenn es ginge. Doch warum geht es nicht?Anders:
TCP_send(&sock, "USER s000ur@freenet.de\r\n\r\n", 1023);
geht nicht, aber
TCP_send(&sock, "USER s000ur@freenet.de\r\n\r\n", strlen("USER s000ur@freenet.de\r\n\r\"));
geht, doch
TCP_send(&sock, sendbuf, 1023);
würde gehen, strlen dann auch.Jetzt ist die Endgültige Frage:
Warum geht
TCP_send(&sock, sendbuf, 1023);
Und TCP_send(&sock, "USER s000ur@freenet.de\r\n\r\n", 1023) nicht???
-
Bei 1023 sendet er noch den Müll mit der nach dem String im Speicher steht.
-
"string"
als literal liegt doch im heap als"string\0garbage..."
, undchar[...] strng; strcpy(strng, "string");
liegt doch dann ebenfalls im speicher unterstrng
als"string\0garbage..."
, warum reagiert dannsend(..., 1023, ...)
anders?