c++ - Socket chat system - broadcasting them to all clients -


communication between server , clients works, server don't forward client messages other connected client's, sender.

i want server react incoming messages broadcasting them clients chat system, keep command system without sharring clients, with sender.

down below sources:

server

    /*server*/ #define win32_lean_and_mean #include <iostream> #include <string> #include <windows.h> #include <winsock2.h> #include <ws2tcpip.h> #include <stdlib.h> #include <stdio.h> #include <process.h>  // need link ws2_32.lib, mswsock.lib, , advapi32.lib #pragma comment (lib, "ws2_32.lib") #pragma comment (lib, "mswsock.lib") #pragma comment (lib, "advapi32.lib")   #define port "3490"  #define server "localhost"   #include <time.h>  wsadata wsa;  socket s , new_socket;  struct sockaddr_in server , client;  int c;  char *message;  std::string line;    dword winapi processclient (lpvoid lpparameter) {     socket acceptsocket = (socket) lpparameter;      // send , receive data.     int bytessent;      int bytesrecv = socket_error;      char sendbuf[2000]="";      char sendbuf2[2000]="";      char recvbuf[2000]="";      char timebuf[128];      sprintf(sendbuf, "hello, it's test server @ %s:%d (commands: 1, 2, exit)\n", server, port);      bytessent = send( acceptsocket, sendbuf, strlen(sendbuf), 0);      if (bytessent == socket_error)     {         printf( "error @ send hello: %ld\n", wsagetlasterror());         goto fin;     }      while (1)     {         _strtime( timebuf );         zeromemory (recvbuf, sizeof(recvbuf));          bytesrecv = recv( acceptsocket, recvbuf, 32, 0);          printf( "%s client said: %s\n", timebuf, recvbuf);            sprintf(sendbuf, "%s client said: %s\n", timebuf, recvbuf);         bytessent = send( acceptsocket, sendbuf, strlen(sendbuf), 0);           if (strcmp(recvbuf, "1") == 0)         {             sprintf(sendbuf, "you typed one\n");             //printf("sent '%s'\n", sendbuf);             bytessent = send( acceptsocket, sendbuf, strlen(sendbuf), 0);              if (bytessent == socket_error)             {                 printf( "error @ send: %ld\n", wsagetlasterror());                 goto fin;             }         }         else if (strcmp(recvbuf, "2") == 0)         {             sprintf(sendbuf, "you typed two\n");             //printf("sent '%s'\n", sendbuf);             bytessent = send( acceptsocket, sendbuf, strlen(sendbuf), 0);              if (bytessent == socket_error)             {                 printf( "error @ send: %ld\n", wsagetlasterror());                 goto fin;             }         }         else if (strcmp(recvbuf, "exit") == 0)         {             printf( "client has logged out\n", wsagetlasterror());             goto fin;         }         else         {            // sprintf(sendbuf, "unknown command\n");             //printf("sent '%s'\n", sendbuf);            //  bytessent = send( acceptsocket, sendbuf, strlen(sendbuf), 0);              if (bytessent == socket_error)             {                // printf( "error @ send: %ld\n", wsagetlasterror());                 goto fin;             }         }     }  fin:     printf("client processed\n");      closesocket(acceptsocket);     return 0; }     int main(int argc , char *argv[]) {      std::cout << ("\ninitialising winsock...");      if (wsastartup(makeword(2,2),&wsa) != 0)     {         std::cout << ("failed. error code : %d",wsagetlasterror());         return 1;     }      printf("initialised.\n");      //create socket     if((s = socket(af_inet , sock_stream , 0 )) == invalid_socket)     {         std::cout << ("could not create socket : %d" , wsagetlasterror());     }      std::cout << ("socket created.\n");      //prepare sockaddr_in structure     server.sin_family = af_inet;     server.sin_addr.s_addr = inaddr_any;     server.sin_port = htons( 3490 );      //bind     if( bind(s ,(struct sockaddr *)&server , sizeof(server)) == socket_error)     {         std::cout << ("bind failed error code : %d" , wsagetlasterror());         exit(exit_failure);     }      puts("bind done");        //listen incoming connections     listen(s , 3);        //accept , incoming connection     std::cout << ("waiting incoming connections...");      c = sizeof(struct sockaddr_in);      while(true){      while((new_socket = accept(s , (struct sockaddr *)&client, &c)) != invalid_socket) {         // create new thread accepted client (also pass accepted client socket).        printf( "client connected.\n");          dword dwthreadid;         createthread (null, 0, processclient, (lpvoid) new_socket, 0, &dwthreadid);     }             }      if (new_socket == invalid_socket)     {         std::cout << ("accept failed error code : %d" , wsagetlasterror());         return 1;     }      closesocket(s);     wsacleanup();      return 0; } 

client

    /*client*/ #define win32_lean_and_mean  #pragma comment(lib,"ws2_32.lib")  #include <iostream> #include <process.h> #include <string> #include <winsock2.h>    socket socket;  #define server "localhost"  int port = 3490;  std::string line;   bool chat = false;    class buffer {  public:     int id;     char message[256]; }sbuffer;    int clientthread() {    char buffer[2000]= "";      for(;; sleep(10))     {         if(recv(socket, buffer, sizeof(sbuffer), null)!=socket_error)         {             strncpy(sbuffer.message, buffer, sizeof(sbuffer.message));              std::cout << "<client:" << sbuffer.id << ":> " << sbuffer.message <<std::endl;              zeromemory (buffer, sizeof(buffer));          }      }      return 0; }   int main(void) {     wsadata wsadat;     if(wsastartup(makeword(2,2),&wsadat)!=0)     {         std::cout<<"winsock error - winsock initialization failed\r\n";         wsacleanup();         system("pause");         return 0;     }      // create our socket       socket=socket(af_inet,sock_stream,ipproto_tcp);     if(socket==invalid_socket)     {         std::cout<<"winsock error - socket creation failed!\r\n";         wsacleanup();         system("pause");         return 0;     }      // resolve ip address hostname     struct hostent *host;     if((host=gethostbyname(server))==null)     {         std::cout<<"failed resolve hostname.\r\n";         wsacleanup();         system("pause");         return 0;     }      // setup our socket address structure     sockaddr_in sockaddr;     sockaddr.sin_port=htons(port);     sockaddr.sin_family=af_inet;     sockaddr.sin_addr.s_addr=*((unsigned long*)host->h_addr);      // attempt connect server     if(connect(socket,(sockaddr*)(&sockaddr),sizeof(sockaddr))!=0)     {         std::cout<<"failed establish connection server\r\n";         wsacleanup();         system("pause");         return 0;     }      // if imode!=0, non-blocking mode enabled.     u_long imode=1;     ioctlsocket(socket,fionbio,&imode);      // main loop     for(;;)     {           // display message server         char buffer[1000];         memset(buffer,0,999);         int indatalength=recv(socket,buffer,1000,0);         std::cout<<buffer;         createthread(null, null, (lpthread_start_routine) clientthread, null, null, null);      for(;; sleep(10))     {         std::string buffer;         std::getline(std::cin, buffer);           if (send(socket, buffer.c_str(), buffer.length(), null) < 1){             }     }              int nerror=wsagetlasterror();          if(nerror!=wsaewouldblock&&nerror!=0)         {             std::cout<<"winsock error code: "<<nerror<<"\r\n";             std::cout<<"server disconnected!\r\n";             // shutdown our socket             shutdown(socket,sd_send);              // close our socket entirely             closesocket(socket);              break;         }           sleep(1000);     }      wsacleanup();      system("pause");     return 0; } 

please me fix it, i'm new socket's. show me how i'm going understand better code , usefull others might need in future.

if need server communicate multiple clients, need kind of collection of connected clients. it's easy send connections, or send connection originating connection.

how differ vastly between c , c++, c++ structures , std::vector.


in pseudo-code this:

while (run_server) {     poll_all_connections();      if (have_new_connection())     {         accept_new_connection();         add_connection_in_collection();     }     else     {         (connection in all_connections())         {             if (have_input(connection))             {                 input = read_from_connection(connection);                  (send_to in all_connections())                     write_to_connection(connection, input)             }         }     } } 

if implement above pseudo-code, input connection sent connections.

don't forget remove connection collection if connection broken (error or disconnect.)


Comments

Popular posts from this blog

php - Why I am getting the Error "Commands out of sync; you can't run this command now" -

linux - Does gcc have any options to add version info in ELF binary file? -

java - Are there any classes that implement javax.persistence.Parameter<T>? -