Problem mit Winsock und Winapi
-
Hallo,
ich will ein Chat Program coden, allerdings hab ich ein Problem: select() läuft solange durch, bis endlich eine Nachricht kommt (neuer Client etc.) und so kann ich nie WM_PAINT etc. behandeln.Dann hab ich mir überlegt: Mach doch einfach einen Server als Konsole und alle anderen greifen mit nem schönen Winapi Programm darauf zu, nächstes Problem: senden kann ich, aber empfangen wie? recv() blockiert ebenfalls!
Gibts da ne Lösung bzw. ein Beispielprogramm?
Danke im Voraus

-
was faselst du da? schonmal was von threads, nonblocking und asynchronous sockets gehört? und bevor du fragst: sufu, google.

-
Du kannst entweder Deine Sockets nicht-blockierend machen, oder aber für die Kommunikation (und für den Listen-Socket des Servers) eigene Threads starten.
-
-
auf c-worker.ch steht zwar was von nichtblockierende Sockets, die werden aber nicht näher behandelt und als schlecht eingestuft

ich versuchs mal

-
hab das gleiche prob wie arrows, habs jetzt versucht zu lösen und ioctlsocket() benutzt, sowie die codes aus den ersten tuts von c-worker.ch:
Client:
#include <winsock2.h> #include <windows.h> #include <stdio.h> //Prototypen int startWinsock(void); int main() { long rc; SOCKET s; SOCKADDR_IN addr; char buf[256]; unsigned long flags = 1; ioctlsocket(s, FIONBIO, &flags); // Winsock starten rc=startWinsock(); if(rc!=0) { printf("Fehler: startWinsock, fehler code: %d\n",rc); return 1; } else { printf("Winsock gestartet!\n"); } // Socket erstellen s=socket(AF_INET,SOCK_STREAM,0); if(s==INVALID_SOCKET) { printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket erstellt!\n"); } // Verbinden memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten addr.sin_family=AF_INET; addr.sin_port=htons(12345); // wir verwenden mal port 12345 addr.sin_addr.s_addr=inet_addr("127.0.0.1"); // zielrechner ist unser eigener rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); if(rc==SOCKET_ERROR) { printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Verbunden mit 127.0.0.1..\n"); } // Daten austauschen while(rc!=SOCKET_ERROR) { printf("\nZeichenfolge eingeben [max 256]: "); gets(buf); send(s,buf,strlen(buf),1); rc=recv(s,buf,256,1); if(rc==0) { printf("Server hat die Verbindung getrennt..\n"); break; } if(rc==SOCKET_ERROR) { printf("Fehler: recv, fehler code: %d\n",WSAGetLastError()); break; } buf[rc]='\0'; printf("\nServer antwortet: %s\n",buf); } closesocket(s); WSACleanup(); return 0; } int startWinsock(void) { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); }Server:
#include <winsock2.h> #include <windows.h> #include <stdio.h> //Prototypen int startWinsock(void); int main() { long rc; SOCKET acceptSocket; SOCKET connectedSocket; unsigned long flags = 1; ioctlsocket(acceptSocket, FIONBIO, &flags); ioctlsocket(connectedSocket, FIONBIO, &flags); SOCKADDR_IN addr; char buf[256]; char buf2[300]; // Winsock starten rc=startWinsock(); if(rc!=0) { printf("Fehler: startWinsock, fehler code: %d\n",rc); return 1; } else { printf("Winsock gestartet!\n"); } // Socket erstellen acceptSocket=socket(AF_INET,SOCK_STREAM,0); if(acceptSocket==INVALID_SOCKET) { printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket erstellt!\n"); } // Socket binden memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(12345); addr.sin_addr.s_addr=ADDR_ANY; rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN)); if(rc==SOCKET_ERROR) { printf("Fehler: bind, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket an port 12345 gebunden\n"); } // In den listen Modus rc=listen(acceptSocket,10); if(rc==SOCKET_ERROR) { printf("Fehler: listen, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("acceptSocket ist im listen Modus....\n"); } // Verbindung annehmen connectedSocket=accept(acceptSocket,NULL,NULL); if(connectedSocket==INVALID_SOCKET) { printf("Fehler: accept, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Neue Verbindung wurde akzeptiert!\n"); } // Daten austauschen while(rc!=SOCKET_ERROR) { rc=recv(connectedSocket,buf,256,1); if(rc==0) { printf("Server hat die Verbindung getrennt..\n"); break; } if(rc==SOCKET_ERROR) { printf("Fehler: recv, fehler code: %d\n",WSAGetLastError()); break; } buf[rc]='\0'; printf("Client sendet: %s\n",buf); sprintf(buf2,"Du mich auch %s",buf); rc=send(connectedSocket,buf2,strlen(buf2),1); } closesocket(acceptSocket); closesocket(connectedSocket); WSACleanup(); return 0; } int startWinsock(void) { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); }Das Problem ist, dass es trotzdem blockiert, was hab ich falsch gemacht?
-
lol du kannst ioctlsocket(s, FIONBIO, &flags); natürlich erst anwenden nachdem der socket mit socket() erstellt wurde.
-
Habs soweit hingebogen, ein Fehler ist noch irgendwo drin - Nachrichten vom Server empfangen kann ich nicht, es kommt immer recv fehler 10035
Hier nochmal der Code vom Client:
#include <winsock2.h> #include <windows.h> #include <stdio.h> //Prototypen int startWinsock(void); int main() { long rc; SOCKET s; SOCKADDR_IN addr; char buf[256]; char buf2[256]; unsigned long flags = 1; // Winsock starten rc=startWinsock(); if(rc!=0) { printf("Fehler: startWinsock, fehler code: %d\n",rc); return 1; } else { printf("Winsock gestartet!\n"); } // Socket erstellen s=socket(AF_INET,SOCK_STREAM,0); if(s==INVALID_SOCKET) { printf("Fehler: Der Socket konnte nicht erstellt werden, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Socket erstellt!\n"); } // Verbinden memset(&addr,0,sizeof(SOCKADDR_IN)); // zuerst alles auf 0 setzten addr.sin_family=AF_INET; addr.sin_port=htons(12345); // wir verwenden mal port 12345 addr.sin_addr.s_addr=inet_addr("127.0.0.1"); // zielrechner ist unser eigener rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); if(rc==SOCKET_ERROR) { printf("Fehler: connect gescheitert, fehler code: %d\n",WSAGetLastError()); return 1; } else { printf("Verbunden mit 127.0.0.1..\n"); } // Daten austauschen ioctlsocket(s, FIONBIO, &flags); while(s != INVALID_SOCKET) { printf("\nZeichenfolge eingeben [max 256]: "); gets(buf); send(s,buf,strlen(buf),0); rc=recv(s,buf2,256,1); buf2[rc]='\0'; if(rc==0) { printf("Server hat die Verbindung getrennt..\n"); break; } if(rc==SOCKET_ERROR) { printf("Fehler: recv, fehler code: %d\n",WSAGetLastError()); break; } printf("\nServer antwortet: %s\n",buf2); } closesocket(s); WSACleanup(); return 0; } int startWinsock(void) { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); }der Code vom Server ist der gleiche

-
der code vom server ist in diesem fall ohne blocking sockets, also der originale vom c-worker.ch tut