Sockets: mehrere clients. das wäre sehr nett wenn ihr mir helfen könntet büdde
-
ich habe den beispielcode von http://www.c-worker.ch/tuts/select.php genommen
da geht es um einen chat-server und -client:server:
#pragma comment( lib, "ws2_32.lib" ) #include <windows.h> #include <winsock2.h> // bei manchan compilern muss man nur windows.h includieren (zB VC++) #include <stdio.h> #define MAX_CLIENTS 10 int startWinsock(void) { WSADATA wsa; return WSAStartup(MAKEWORD(2,0),&wsa); } int main() { long rc; SOCKET acceptSocket; //SOCKET connectedSocket; SOCKADDR_IN addr; char buf[256]; char buf2[300]; // zusätzliche Variabeln FD_SET fdSet; SOCKET clients[MAX_CLIENTS]; int i; // 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=INADDR_ANY; // gewisse compiler brauchen hier 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"); } for(i=0;i<MAX_CLIENTS;i++) { clients[i]=INVALID_SOCKET; } while(1) { FD_ZERO(&fdSet); // Inhalt leeren FD_SET(acceptSocket,&fdSet); // Den Socket der verbindungen annimmt hinzufügen // alle gültigen client sockets hinzufügen (nur die die nicht INVALID_SOCKET sind) for(i=0;i<MAX_CLIENTS;i++) { if(clients[i]!=INVALID_SOCKET) { FD_SET(clients[i],&fdSet); } } rc=select(0,&fdSet,NULL,NULL,NULL); // nicht vergessen den ersten parameter bei anderen betriebssystem anzugeben if(rc==SOCKET_ERROR) { printf("Fehler: select, fehler code: %s\n",WSAGetLastError()); return 1; } // acceptSocket is im fd_set? => verbindung annehmen (sofern es platz hat) if(FD_ISSET(acceptSocket,&fdSet)) { // einen freien platz für den neuen client suchen, und die verbingung annehmen for(i=0;i<MAX_CLIENTS;i++) { if(clients[i]==INVALID_SOCKET) { clients[i]=accept(acceptSocket,NULL,NULL); printf("Neuen Client angenommen (%d)\n",i); break; } } } // prüfen wlecher client sockets im fd_set sind for(i=0;i<MAX_CLIENTS;i++) { if(clients[i]==INVALID_SOCKET) { continue; // ungültiger socket, d.h. kein verbunder client an dieser position im array } if(FD_ISSET(clients[i],&fdSet)) { rc=recv(clients[i],buf,256,0); // prüfen ob die verbindung geschlossen wurde oder ein fehler auftrat if(rc==0 || rc==SOCKET_ERROR) { printf("Client %d hat die Verbindung geschlossen\n",i); closesocket(clients[i]); // socket schliessen clients[i]=INVALID_SOCKET; // seinen platz wieder freigeben } else { buf[rc]='\0'; // daten ausgeben und eine antwort senden printf("Client %d hat folgendes gesandt: %s\n",i,buf); // antwort senden sprintf(buf2,"Du mich auch %s\n",buf); send(clients[i],buf2,(int)strlen(buf2),0); } } } } }client:
#include <windows.h> #include <winsock2.h> #include <stdio.h> //Prototypen int startWinsock(void); long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr); int main(int argc, char** argv) { long rc; SOCKET s; SOCKADDR_IN addr; char buf[256]; if(argc<2) { printf("Usage: sock <hostname oder ip des servers>\n"); return 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 rc=getAddrFromString(argv[1],&addr); if(rc==SOCKET_ERROR) { printf("IP für %s konnte nicht aufgeloest werden\n", argv[1]); return 1; } else { printf("IP aufgeloest!\n"); } 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),0); rc=recv(s,buf,256,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; } 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); } long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr) { long rc; unsigned long ip; HOSTENT* he; /* Parameter prüfen */ if(hostnameOrIp==NULL || addr==NULL) return SOCKET_ERROR; /* eine IP in hostnameOrIp ? */ ip=inet_addr(hostnameOrIp); /* bei einem fehler liefert inet_addr den Rückgabewert INADDR_NONE */ if(ip!=INADDR_NONE) { addr->sin_addr.s_addr=ip; return 0; } else { /* Hostname in hostnameOrIp auflösen */ he=gethostbyname(hostnameOrIp); if(he==NULL) { return SOCKET_ERROR; } else { /*die 4 Bytes der IP von he nach addr kopieren */ memcpy(&(addr->sin_addr),he->h_addr_list[0],4); } return 0; } }meine frage ist: ist es möglich bei dem server für jeden clienten ein neues fenster zu öffnen damit man den chatt voll ausnutzen kann?
-
Dieser Thread wurde von Moderator/in HumeSikkins aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.