ich schreibe gerade an einem kleinen Programm in C, das eine einfache TCP-Verbindung zu einem beliebigen Host an einem beliebigen Port aufbauen kann. In der Theorie recht simpel, in der Praxis auch, wären da nicht.....
.....ja, wären da nicht einige, ich nenne es mal Defizite in meiner C-Praxis, die ich gerade auszubessern Versuche. Daher bin ich auch bei folgenden Problem im ersten Moment etwas ratlos. Dieses Mini-Programm (nur zum Testen der sprintf-Funktion) funktioniert ohne Fehler. Man beachte die Zeile mit der sprintf-Funktion:
#include <stdio.h> int main(void) { char send_buf[256]; char* command; printf("command: "); scanf("%s", command); sprintf(send_buf, "%s\n\n", command); puts(send_buf); return 0; }
Das folgende Listing ist das Programm, das die TCP-Verbindung aufbauen kann. Leider macht verursacht diese Funktion einen fehlerhaften Speicherzugriff und das Programm wird von XP beendet. In den Zeilen mit den Comments vermute ich das Problem, da das Programm bis dahin alle Ausgaben liefert:
#include <windows.h> #include <winsock2.h> #include <stdio.h> #include <stdlib.h> void perr_exit(char* msg, int ret_code) { printf("%s, Error: ",msg); printf("%d\n",ret_code); exit(ret_code); } void usage(char* progname) { printf("\nUsage:\t"); printf("%s <Host> <Port>\n",progname); printf("\tHost: Host to connect\n"); printf("\tPort: Port to connect\n"); exit(0); } int main(int argc, char** argv) { char* host; char* command; char buf[1024]; char send_buf[256]; char recv_buf[256]; long rc; long port; SOCKET s; SOCKADDR_IN addr; WSADATA wsa; HOSTENT* hent; if(argc == 3) { host=argv[1]; port=atol(argv[2]); } else { usage(argv[0]); } if(WSAStartup(MAKEWORD(2,0),&wsa)) perr_exit("WSAStartup failed",WSAGetLastError()); addr.sin_family=AF_INET; addr.sin_port=htons(port); printf("Host: %s\n",host); printf("Port: %d\n",port); printf("Connecting....\n"); if((addr.sin_addr.s_addr=inet_addr(host))==INADDR_NONE) { if(!(hent=gethostbyname(host))) perr_exit("Cannot resolve Host",WSAGetLastError()); strncpy((char*)&addr.sin_addr.s_addr,hent->h_addr,4); if(addr.sin_addr.s_addr==INADDR_NONE) perr_exit("Cannot resolve Host",WSAGetLastError()); } if((s=socket(AF_INET,SOCK_STREAM,0))==INVALID_SOCKET) perr_exit("Cannot create Socket",WSAGetLastError()); if( connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR))) perr_exit("Cannot connect",WSAGetLastError()); printf("Connected to %s\n",host); printf("Send command: "); scanf("%s", command); //scanf("%s", send_buf); sprintf(send_buf, "%s\n\n", command); // *** error *** printf("debug send_buf: \"%s\n\"", send_buf); // *** not shown *** if((send(s,send_buf,strlen(send_buf),0))<strlen(send_buf)) perr_exit("Cannot send Data",WSAGetLastError()); printf("Command was send...\n"); while((rc=recv(s,recv_buf,255,0))>0) { recv_buf[rc]='\0'; printf("%s",recv_buf); } closesocket(s); return 0; }
Ändert man die Stelle im Code in der Form um, wie ich es auch in den Comments angedeutet habe, also indem man auf die sprintf-Funktion verzichtet und die Befehlszeile direkt in send_buf einliest, gibt es keine Probleme. Ich möchte die sprintf-Funktion, die im ersten Beispiel ja auch funktioniert, aber gerne in meinem Programm einsetzen.
Das ganze ist mit Absicht bisher mit Absicht sehr einfach gehalten, dennoch bin ich verwundert, dass die gleiche Funktion einmal funktioniert (Testprogramm, erstes Listing) und im einmal nicht.
Woran kann das liegen?
MfG aus HH
ps: Das Listing basiert auf diesem Winsock-Tutorial: http://www.c-worker....nsock/getpage.c
ps2: ich hab's. Dämliche Pointer, char* command, ich glaub' c will immer eine Grössenangabe haben, mit char command[256] funktioniert es.
Dieser Beitrag wurde von 2cool bearbeitet: 13. August 2006 - 13:04