Socket/Network Library
-
-
Thx, der Artikel wird mir sicher helfen.
-
roan312 schrieb:
Ich denke select() ist auch blockierend?
-Foo- schrieb:
oder man könnte auch einfach nicht blockierende sockets erstellen...
Wie?
select mit nem timeout von 0 ist nicht blockierend. 0 sekunden waren blockiert ja nix oder?
fcntl() <-- keine ahung obs das auch unter windows gibt...
und sonnst, wie wäre es mal bei google "non-blocking socket windows" einzutippen?
aber ich bevorzuge die methode mit select ohne timeout..., denn dort blockiert z.B. das connect(...) oder accept(...) weiterhin (was auch mit select umgangen werden kann, wenicstens beim accept(...)
-
Danke, das wär auch einen Versuch wert, ich werde es aber erstmal mit Asynchronen Sockets versuchen.
-
select mit Timeout 0 blockiert solange bis sich was bei den Sockets geändert hat.
Mit ioctlsocket setzt man die Sockets unter Windows in den Non-Blocking Modus. (muss vor select gemacht werden)
-
(muss vor select gemacht werden)
Ups, kann auch nach select gemacht werden, aber sollte auf jeden Fall vor dem recv, send, ..., gemacht werden.
-
multiplexer schrieb:
select mit Timeout 0 blockiert solange bis sich was bei den Sockets geändert hat.
Mit ioctlsocket setzt man die Sockets unter Windows in den Non-Blocking Modus.
Danke, hab ich auch gerade gefunden
: http://www.adp-gmbh.ch/win/misc/sockets.html
Scheint mir doch um einiges unkomplizierter zu sein als die A.Sockets,
mal in dem MSDN nachschlagen wie das genauer...
-
Scheint mir doch um einiges unkomplizierter zu sein als die A.Sockets
Der Schein trügt.
select ist auf der Winsock Lame-List.
http://tangentsoft.net/wskfaq/articles/lame-list.html Punkt 23
-
multiplexer schrieb:
select mit Timeout 0 blockiert solange bis sich was bei den Sockets geändert hat.
Mit ioctlsocket setzt man die Sockets unter Windows in den Non-Blocking Modus. (muss vor select gemacht werden)
Wenn timeout den Wert 0 hat, also ein timeval mit sowohl tv_sec als auch tv_usecs auf 0 gesetzt, kehrt sofort zurück
Wenn jedoch nur eine Null-Adresse, also NULL oder 0 übergeben wird, so wartet es unendlich lange:aus der man-page:
timeout is an upper bound on the amount of time elapsed before select
returns. It may be zero, causing select to return immediately. (This is
useful for polling.) If timeout is NULL (no timeout), select can block
indefinitely.
-
ach so meintest du das.
-
Ich werd sowieso kein select benutzen, arbeite lieber mit std::list<...>.
-
und welche c api unterstützt std::list?
-
c. schrieb:
und welche c api unterstützt std::list?
War die Frage ernst gemeint?
Falls ja, ich meinte, ich würde die n.b.-Sockets lieber in einen Container packen und dann die recv() Funktionen einzeln aufrufen, - anstatt sie alle über select() markieren zu lassen.Hab schon angefangen alles fein säuberlich in Klassen zu verpacken. ^^
-
darf man das ergebnis sehen? ich weiß nicht wie du das meinst.
pollst du die sockets etwa und erzeugst damit 100% CPU Auslastung?
-
c. schrieb:
darf man das ergebnis sehen? ich weiß nicht wie du das meinst.
pollst du die sockets etwa und erzeugst damit 100% CPU Auslastung?
Fast, ca. 94%.
Ich hab später aber noch haufenweise anderes Zeug in der Main-Schleife, desshalb macht das nichts.
Außerdem bau ich eine Modulo Abfrage je nach Framerate für den Aufruf der Netzwerkfunktionen ein.Der Testcode sieht so aus... (Rein Technisch und alles so runtergerattert
)
//#pragma comment (lib,"ws2_32.lib"); #include <windows.h> //#include <winsock2.h> #include <stdio.h> #include <list> //Prototypen int startWinsock(void); int main() { long rc; SOCKET acceptSocket; SOCKET connectedSocket; SOCKADDR_IN addr; char buf[256]; char buf2[300]; int iMode = 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 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=inet_addr("127.0.0.1"); ioctlsocket(acceptSocket,FIONBIO,(u_long FAR*) &iMode); 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 while(1) { connectedSocket=accept(acceptSocket,NULL,NULL); if(connectedSocket==INVALID_SOCKET) { if(WSAGetLastError()==WSAEWOULDBLOCK) continue; printf("Fehler: accept, fehler code: %d\n",WSAGetLastError()); system("pause"); return 1; } else { printf("Neue Verbindung wurde akzeptiert!\n"); break; } } //system("pause"); // Daten austauschen while(rc!=SOCKET_ERROR || WSAGetLastError()==WSAEWOULDBLOCK) { rc=recv(connectedSocket,buf,256,0); if(rc==0) { printf("Server hat die Verbindung getrennt..\n"); break; } if(rc==SOCKET_ERROR) { if(WSAGetLastError()==WSAEWOULDBLOCK) continue; 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),0); } system("pause"); closesocket(acceptSocket); closesocket(connectedSocket); WSACleanup(); return 0; } int startWinsock(void) { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); }
(Kommuniziert zb. mit dem C-Worker.ch Standard-Client aus Tutorial 1)
EDIT: Pardon, da sieht man noch garnichts von der genannten Architektur.
EDIT: Ich brauch noch ein weilchen um die Lib fertig zu stellen, dann Poste ich EDIT: bei bedarf ein paar Codeschnippsel.