Server von c-worker und hierzu ein Client...



  • Hallo leute ich möchte gern ein client server programm erstellen, diese sollen untereinander strings versenden können. Habe mir den SimpleSocketServer von c-worker.ch angeschaut: http://www.c-worker.ch/winsock/SimpleSocketServer.cpp

    Doch wie sieht hierzu ein simpler client aus, könntet ihr mir bitte ein beispiel zeigen.



  • Hab einen client/server gefunden auch von c-worker, eigentlich ist das ein Chat aber es können hier mehrere clients mit dem server eine verbindung aufbauen und das habe ich gesucht 🙂
    Sobald ich eine verbindung mit dem server hergestelt habe, kann ich mit dem server chatten, doch wie bekomme ich das was ich eintippe auch in der ausgabe zu sehen?

    Client
    /*************************************************************************** 
    Name:             selectchatclient.cpp 
    Autor:            www.c-worker.ch 
    Comments:      deutsch/english 
    
    Beschreibung:  
    Zeigt wie man blocking calls umgehen kann indem man select verwendet. 
    Dies ist der Client für selectchatsrv.cpp 
    ACHTUNG: du wirst nicht sehen was du eingibst, bis du enter drückst 
    um die nachricht abzusenden!! 
    
    Description: 
    The client for selectchatsrv.cpp 
    ATTENTION: you wan't see what you type, until you press enter to 
    send the message! 
    
    ***************************************************************************/ 
    
    #include <stdlib.h> 
    #include <stdio.h> 
    #include <windows.h> 
    #include <winsock.h> 
    #include <conio.h> 
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    #pragma comment(lib,"wsock32.lib")
    
    // Startet Winsock und gibt einige Infos zur Version aus 
    // Starts winsock and dumps some infos about the version 
    int startWinsock() 
    { 
       int rc; 
       WSADATA wsaData; 
       rc=WSAStartup(MAKEWORD(2,0),&wsaData); 
       printf("Return Code: %d\n",rc); 
       if(rc==SOCKET_ERROR) 
       { 
          printf("Error, exiting!\n"); 
          return rc; 
       } 
       printf("Winsock started:\n"); 
       printf("Version: %d.%d\n",LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion)); 
       printf("High Version: %d.%d\n",LOBYTE(wsaData.wHighVersion),HIBYTE(wsaData.wHighVersion)); 
       printf("Description: %s\n",wsaData.szDescription); 
       printf("System Status: %s\n",wsaData.szSystemStatus); 
       return 0; 
    } 
    
    // Sucht eine IP anhand eines Strings, der entweder die IP als String 
    // oder einen Hostname enthalten kann 
    // Searches an IP based on a string, which can contain an IP as string 
    // or a hostname 
    long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr) 
    { 
       long rc; 
       unsigned long ip; 
    
       HOSTENT* he; 
    
       if(hostnameOrIp==NULL || addr==NULL) 
          return SOCKET_ERROR; 
       ip=inet_addr(hostnameOrIp); 
    
       if(ip!=INADDR_NONE)
       { 
          addr->sin_addr.s_addr=ip; 
          return 0; 
       } 
       else 
       { 
          he=gethostbyname(hostnameOrIp); 
          if(he==NULL) 
    	  { 
             return SOCKET_ERROR; 
          } 
    	  else 
    	  { 
             memcpy(&(addr->sin_addr),he->h_addr_list[0],4); 
          } 
          return 0; 
       } 
    } 
    
    // main... 
    int main(int argc, char* argv[]) 
    { 
    	if(argc > 2)
    	{
    		char* HOST = argv[1];
    		int PORT = atoi(argv[2]);
    
    		SOCKET s; 
    		SOCKADDR_IN addr; 
    		char c; 
    		char buf[1024]; 
    		char inpBuf[1024]; 
    		int inpBufPos=0; 
    		fd_set fdSetRead; 
    		TIMEVAL timeout; 
    		int rc; 
    
    		// start winsock 
    		rc=startWinsock(); 
    		if(rc==SOCKET_ERROR) 
    		return 1; 
    
    		// addr vorbereiten, hostname auflösen 
    		// prepare addr, resolve hostname 
    		memset(&addr,0,sizeof(SOCKADDR_IN)); 
    		addr.sin_family=AF_INET; 
    		addr.sin_port=htons(PORT); 
    		rc=getAddrFromString(HOST, &addr); 
    		if(rc==SOCKET_ERROR) 
    		{ 
    		printf("Error: Cannot resolve Host %s\n", HOST); 
    		return 1; 
    		} 
    
    		// socket erstellen 
    		// create socket 
    		s=socket(PF_INET,SOCK_STREAM,0); 
    		if(s==INVALID_SOCKET) 
    		{ 
    		printf("Error, cannot create socket: %d\n",WSAGetLastError()); 
    		return 1; 
    		} 
    
    		// verbinden.. 
    		// connect.. 
    		printf("Connecting...\n"); 
    		rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); 
    		if(rc==SOCKET_ERROR) 
    		{ 
    		printf("Error: connect failed: %d\n",WSAGetLastError()); 
    		return 1; 
    		} 
    
    		printf("\n"); 
    
    		while(rc!=SOCKET_ERROR) 
    		{ 
    			// keyboard input ? 
    			while(kbhit()) 
    			{ 
    			 c=getch(); 
    			 if(c==13) 
    			 { 
    				rc=send(s,inpBuf,inpBufPos,0); 
    				inpBuf[0]='\0'; 
    				inpBufPos=0; 
    			 } 
    			 else 
    			 { 
    				inpBuf[inpBufPos++]=c; 
    			 } 
    			} 
    			inpBuf[inpBufPos]='\0'; 
    
    			// fd_set und timeout vorbereiten 
    			// prepare fd_set and timeout 
    			FD_ZERO(&fdSetRead); 
    			FD_SET(s,&fdSetRead); 
    			timeout.tv_sec=0; 
    			timeout.tv_usec=0; 
    
    			// prüfen ob ein socket bereit ist, da timeout=0 kehrt die funktion 
    			// sofort wieder zurück nach dem aufruf. 
    			// achtung: das timeout auf 0 setzen oder als paremeter NULL mitgeben 
    			// ist NICHT das gleiche. auf 0 gesetzt kehrt sofort zurück, während 
    			// NULL blockt. 
    			// check if any socket is ready (timeout=0, the function returns without delay) 
    			while((rc=select(0,&fdSetRead,NULL,NULL,&timeout))>0) 
    			{ 
    				rc=recv(s,buf,1023,0); 
    				// server hat die verbindung beendet ? 
    				// server closed connection ? 
    				if(rc==0) 
    				{ 
    					printf("Server closed connection!\n"); 
    					return 1; 
    				// fehler: beenden! 
    				// error: abort! 
    				} else if(rc==SOCKET_ERROR) 
    				{ 
    					printf("Error: recv failed: %d\n",WSAGetLastError()); 
    					return 1; 
    				} 
    				// empfangene daten ausgeben 
    				// print received data 
    				buf[rc]='\0'; 
    				printf("%s\n",buf); 
    			} 
    
    			}//Ende while
    
    			// aufräumen 
    			// cleanup.. 
    			closesocket(s); 
    			WSACleanup(); 
    			printf("Client shutdown, press any key to exit\n"); 
    			getch(); 
    
    	   }
    	   else	
    	   {
    		   cout << "client HOST PORT" << endl;
    	   }
    	   return 0; 
    
    }
    

    [EDIT] Vom Autor:

    Bitte beachtet das man im Client den eingegebenen Text erst sieht wenn man ihn mit Return abschickt.

    Kann man das nicht ändern?



  • habs hinbekommen das man die eingabe sieht und habe gleich die while schleife in eine do-while schleife geändert, doch bei dieser eingabe wird nicht der ganze string versendet dieser bricht bei einem leerzeichen ab, was kann man hier dagegen tun?

    string str; //Eingabe String
    
    		do
    		{
    			cout << "Eingabe:";
    
    			getline(cin, str);
    
    			istringstream cmdline (str);
    			string input;
    			vector<string> params;
    
    			if (cmdline >> input) 
    			{
    				string tmp;
    				while (cmdline >> tmp) 
    				{
    					params.push_back (tmp);
    				}
    				strcpy(inpBuf,input.c_str());
    
    				rc=send(s,inpBuf,strlen(inpBuf),0); 
    cout << "send:" << inpBuf << endl; //sobald ich hier ein string mit leerzeichein eingebe wird nur das erste wort hier ausgegeben :(
    

Anmelden zum Antworten