C中的多线程服务器/客户端实现

 卝軎亟_621 发布于 2023-01-30 19:33

我刚开始学习基本的网络概念.我正在尝试在C中实现多线程服务器 - 客户端编程.但问题是不是为客户端运行多个windows/terminal/instance,我应该使用fork()来创建客户端的子代.so通过创建客户端的子节点将创建多个客户端.现在这些子客户端中的每一个都将在线程上与服务器通信.

之前我创建了类似的编程,但是对于多个客户端,您必须为客户端打开多个窗口并运行所有这些窗口.

我无法修改我的代码(在服务器和客户端都有.我认为服务器一个是好的.但我不知道在客户端程序中fork()的位置以及应该进行哪些更改).

实际上我不想打开多个窗口来运行多个客户端,这就是为什么我使用fork()创建它的多个副本.是否有任何其他方式我可以创建多个客户端并将它们连接到我的服务器prog通过线程.

服务器:

// socket server example, handles multiple clients using threads

#include
#include    //strlen
#include    //strlen
#include
#include //inet_addr
#include    //write
#include //for threading , link with lpthread

//the thread function
void *connection_handler(void *);

int main(int argc , char *argv[])
{
    int socket_desc , client_sock , c , *new_sock;
    struct sockaddr_in server , client;

    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 3000 );

    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
        //print the error message
        perror("bind failed. Error");
        return 1;
    }
    puts("bind done");

    //Listen
    listen(socket_desc , 3);

    //Accept and incoming connection
    puts("Waiting for incoming connections...");
    c = sizeof(struct sockaddr_in);

        c=sizeof(struct sockaddr_in);
       while(client_sock=accept(socket_desc,(struct sockaddr*)&client,(socklen_t*)&c))
       {
        puts("Connection accepted");

        pthread_t sniffer_thread;
        new_sock = malloc(1);
        *new_sock = client_sock;

        if( pthread_create( &sniffer_thread , NULL ,  connection_handler , (void*) new_sock) < 0)
        {
            perror("could not create thread");
            return 1;
        }

        puts("Handler assigned");
    }

    if (client_sock < 0)
    {
        perror("accept failed");
        return 1;
    }
    return 0;
}
/*
  This will handle connection for each client
  */
void *connection_handler(void *socket_desc)
{
    //Get the socket descriptor
    int sock = *(int*)socket_desc;
    int n;

        char    sendBuff[100], client_message[2000];

      while((n=recv(sock,client_message,2000,0))>0)
      {

        send(sock,client_message,n,0);
      }
      close(sock);

      if(n==0)
      {
        puts("Client Disconnected");
      }
      else
      {
        perror("recv failed");
      }
    return 0;
}

客户:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define MAX_SIZE 50

int main()
{
    int sock_desc;
    struct sockaddr_in serv_addr;
    char sbuff[MAX_SIZE],rbuff[MAX_SIZE];

    if((sock_desc = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        printf("Failed creating socket\n");

    bzero((char *) &serv_addr, sizeof (serv_addr));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serv_addr.sin_port = htons(3000);

    if (connect(sock_desc, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
        printf("Failed to connect to server\n");
        return -1;
    }

    printf("Connected successfully - Please enter string\n");
    while(fgets(sbuff, MAX_SIZE , stdin)!=NULL)
    {
      send(sock_desc,sbuff,strlen(sbuff),0);

          if(recv(sock_desc,rbuff,MAX_SIZE,0)==0)
           printf("Error");
          else
           fputs(rbuff,stdout);

       bzero(rbuff,MAX_SIZE);//to clean buffer-->IMP otherwise previous word characters also came
    }
        close(sock_desc);
    return 0;

}

sujin.. 7

您可以使用线程创建多个客户端.为每个客户端创建一个单独的线程,然后从线程处理程序连接到服务器.我不确定这是不是一个好方法.

码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define MAX_SIZE 50
#define NUM_CLIENT 5
void *connection_handler(void *socket_desc);
int main()
{
    int socket_desc , new_socket , c , *new_sock, i;
    pthread_t sniffer_thread;
    for (i=1; i<=NUM_CLIENT; i++) {
        if( pthread_create( &sniffer_thread , NULL ,  connection_handler , (void*) i) < 0)
        {
            perror("could not create thread");
            return 1;
        }
        sleep(3);
    }
    pthread_exit(NULL);
    return 0;
}

void *connection_handler(void *threadid)
{
    int threadnum = (int)threadid;
    int sock_desc;
    struct sockaddr_in serv_addr;
    char sbuff[MAX_SIZE],rbuff[MAX_SIZE];

    if((sock_desc = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        printf("Failed creating socket\n");

    bzero((char *) &serv_addr, sizeof (serv_addr));

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serv_addr.sin_port = htons(8888);

    if (connect(sock_desc, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
        printf("Failed to connect to server\n");
    }

    printf("Connected successfully client:%d\n", threadnum);
    while(1)
    {
        printf("For thread : %d\n", threadnum);
        fgets(sbuff, MAX_SIZE , stdin);
        send(sock_desc,sbuff,strlen(sbuff),0);

        if(recv(sock_desc,rbuff,MAX_SIZE,0)==0)
            printf("Error");
        else
           fputs(rbuff,stdout);

        bzero(rbuff,MAX_SIZE);
        sleep(2);
    }
    close(sock_desc);
    return 0;
}

为了理解目的,我使用了sleep.

REF:

http://www.amazon.com/UNIX-Network-Programming-Richard-Stevens/dp/0139498761

http://beej.us/guide/bgnet/

https://computing.llnl.gov/tutorials/pthreads/

2 个回答
  • 您可以使用线程创建多个客户端.为每个客户端创建一个单独的线程,然后从线程处理程序连接到服务器.我不确定这是不是一个好方法.

    码:

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    #define MAX_SIZE 50
    #define NUM_CLIENT 5
    void *connection_handler(void *socket_desc);
    int main()
    {
        int socket_desc , new_socket , c , *new_sock, i;
        pthread_t sniffer_thread;
        for (i=1; i<=NUM_CLIENT; i++) {
            if( pthread_create( &sniffer_thread , NULL ,  connection_handler , (void*) i) < 0)
            {
                perror("could not create thread");
                return 1;
            }
            sleep(3);
        }
        pthread_exit(NULL);
        return 0;
    }
    
    void *connection_handler(void *threadid)
    {
        int threadnum = (int)threadid;
        int sock_desc;
        struct sockaddr_in serv_addr;
        char sbuff[MAX_SIZE],rbuff[MAX_SIZE];
    
        if((sock_desc = socket(AF_INET, SOCK_STREAM, 0)) < 0)
            printf("Failed creating socket\n");
    
        bzero((char *) &serv_addr, sizeof (serv_addr));
    
        serv_addr.sin_family = AF_INET;
        serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
        serv_addr.sin_port = htons(8888);
    
        if (connect(sock_desc, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
            printf("Failed to connect to server\n");
        }
    
        printf("Connected successfully client:%d\n", threadnum);
        while(1)
        {
            printf("For thread : %d\n", threadnum);
            fgets(sbuff, MAX_SIZE , stdin);
            send(sock_desc,sbuff,strlen(sbuff),0);
    
            if(recv(sock_desc,rbuff,MAX_SIZE,0)==0)
                printf("Error");
            else
               fputs(rbuff,stdout);
    
            bzero(rbuff,MAX_SIZE);
            sleep(2);
        }
        close(sock_desc);
        return 0;
    }
    

    为了理解目的,我使用了sleep.

    REF:

    http://www.amazon.com/UNIX-Network-Programming-Richard-Stevens/dp/0139498761

    http://beej.us/guide/bgnet/

    https://computing.llnl.gov/tutorials/pthreads/

    2023-01-30 19:35 回答
  • 首先,如果您fork(),您将创建其他进程,而不是其他线程.要创建其他线程,您需要使用pthread_create.

    其次,当你是学生时,这里的规范答案是"读斯蒂芬斯".这不仅是我们在编写套接字I/O例程方面经验丰富的宝贵工具,而且它还包含非线程非分叉异步I/O的示例,以及添加线程和分叉的各种方法.我相信你想要的是:http://www.amazon.com/Programming-Environment-Addison-Wesley-Professional-Computing/dp/0321637739(第14章,如果内存服务).这应该在你的大学图书馆.

    2023-01-30 19:35 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有