Как я могу заставить мой сервер принимать несколько клиентов в C? (Программирование сокетов TCP) - PullRequest
1 голос
/ 21 апреля 2019

Я работаю в чате TCP-IP, и мой сервер может принимать только одного клиента. Этот клиент может отправлять сообщения, и сервер правильно записывает их обратно в терминал, в котором он работает.

Проблема в том, что я хотел бы, чтобы мой сервер принимал несколько клиентов, но я не знаю, возможно ли это без fork () или pthread.

Мои знания по программированию сокетов очень просты, это домашнее задание для меня в университете, и я честно застрял.

Это в основном все, чего я мог достичь, просматривая учебники и читая коды:

Client.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define BUFSIZE 1024                      
#define PORT_NO 2001                      
#define error(a,b) fprintf(stderr, a, b)  

int main(int argc, char *argv[] ){ 

   int fd;                     
   int flags;                      
   struct sockaddr_in server;      
   struct sockaddr_in client;      
   int server_size;                
   int client_size;                
   int bytes;                      
   int rcvsize;                    
   int trnmsize;                   
   int err;                        
   char on;                        
   char buffer[BUFSIZE+1];         
   char server_addr[16];          

   on                     = 1; 
   flags                  = 0;    
   sprintf(server_addr, "%s", argv[1]);
   server.sin_family      = AF_INET;
   server.sin_addr.s_addr = inet_addr(server_addr);
   server.sin_port        = htons(PORT_NO);
   server_size            = sizeof server;
   client_size            = sizeof client;

   fd = socket(AF_INET, SOCK_STREAM, 0 ); 
   if ( fd < 0 ) { 
      error("%s: Socket creation error\n",argv[0]);
      exit(1);
      }

   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof on);
   setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof on);

   err = connect( fd, (struct sockaddr *) &server, server_size);
   if ( err < 0 ) {
      error("%s: Cannot connect to server\n",argv[0]);
      exit(2);
      }

while (1)
   {
    printf(" Message: ");
    scanf("%s",buffer);
    bytes=strlen(buffer)+1;

    trnmsize = send( fd, buffer, bytes, flags );
    if ( trnmsize < 0 ) { 
            error("%s: Cannot send to server\n",argv[0]);
            exit(3);
        }

    printf (" %i bytes have been sent to server.\n", trnmsize-1);

    rcvsize = recv( fd, buffer, bytes, flags );
    if ( rcvsize < 0 ) {
            error("%s: Cannot receive from the socket\n",argv[0]);
            exit(4);
        }

    if (strcmp(buffer,"Transmit is OK."))
            printf (" Acknowledgement has been received from server.\n");
    else
            printf(" Acknowledgement error!");

   }

   close(fd);
   exit(0);
   }

Server.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> 
#include <string.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

#define BUFSIZE 1024                      
#define PORT_NO 2001                      
#define error(a,b) fprintf(stderr, a, b)  

int main(int argc, char *argv[] ){

   int fd;                 
   int fdc;                       
   int flags;                      
   struct sockaddr_in server;     
   struct sockaddr_in client;     
   unsigned int server_size;       
   unsigned int client_size;       
   int bytes;                      
   int rcvsize;                    
   int trnmsize;                   
   int err;                        
   char on;                        
   char buffer[BUFSIZE+1];         

   on                     = 1; 
   flags                  = 0; 
   bytes                  = BUFSIZE;
   server.sin_family      = AF_INET;
   server.sin_addr.s_addr = INADDR_ANY;
   server.sin_port        = htons(PORT_NO); 
   server_size            = sizeof server; 
   client_size            = sizeof client; 

   fd = socket(AF_INET, SOCK_STREAM, 0 ); 
   if ( fd < 0 ) {
      error("%s: Socket creation error\n",argv[0]);
      exit(1);
      }

   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof on); 
   setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on, sizeof on);

   err = bind( fd, (struct sockaddr *) &server, server_size);
   if ( err < 0 ) { 
      error("%s: Cannot bind to the socket\n",argv[0]);
      exit(2);
      }

   err = listen( fd, 10);
   if ( err < 0 ) { 
      error("%s: Cannot listen to the socket\n",argv[0]);
      exit(3);
      }

   fdc = accept (fd, (struct sockaddr *) &client, &client_size);
   if ( fdc < 0 ) {
      error("%s: Cannot accept on socket\n",argv[0]);
      exit(4);
      }

while (1)
{

        rcvsize = recv( fdc, buffer, bytes, flags );
        if ( rcvsize < 0 ) { 
            error("%s: Cannot receive from the socket\n",argv[0]);
            exit(5);
        }

        printf (" %i bytes have been received from client.\n Message: %s \n",
           rcvsize-1, buffer);

        sprintf(buffer,"Transmit is OK.");
        bytes = strlen(buffer) + 1;
        trnmsize = send( fdc, buffer, bytes, flags );
        if ( trnmsize < 0 ) { 
            error("%s: Cannot send to server\n",argv[0]);
            exit(6);
        }

        printf (" Acknowledgement has been sent to client.\n");

}

    close (fdc);
    close (fd);
    exit(0);
    }

Заранее спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...