用C多线程服务器/客户端的实现 [英] multithread server/client implementation in C

查看:148
本文介绍了用C多线程服务器/客户端的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始学习基本的网络concepts.I想实现多线程服务器 - 客户端PROG在C.but问题,而不是运行多个窗口/终端/实例,为客户,我应该使用fork()来创建通过创建客户端多个客户端的儿童client.so的孩子会created.now每个子客户端都与一个线程的服务器进行通信。

此前我创建了一个类似的前卫,但对于多个客户端,你必须打开多个窗口,为客户和运行所有的人。

我无法在这里修改我的code(无论是在服务器和客户端ones.I认为服务器一个是ok.but我有不知道从哪里调用fork()客户端程序和什么样的变化应)。

其实我不想打开多个窗口同时运行多个客户端,这就是为什么我使用fork()的在那里创建it.Is的多个副本由我可以创建多个客户端的任何其他方式,并将它们连接到我通过线程服务器PROG。

服务器:

  //插槽服务器,例如,处理使用线程的多个客户端#包括LT&;&stdio.h中GT;
#包括LT&;&string.h中GT; // strlen的
#包括LT&;&stdlib.h中GT; // strlen的
#包括LT&; SYS / socket.h中>
#包括LT&; ARPA / inet.h> // inet_addr
#包括LT&;&unistd.h中GT; //写
#包括LT&;&pthreads.h中GT; //为线程,链接与lpthread//线程函数
无效* connection_handler(无效*);INT主(INT ARGC,CHAR *的argv [])
{
    INT socket_desc,client_sock,C,* new_sock;
    结构SOCKADDR_IN服务器,客户端;    //创建插座
    socket_desc =插座(AF_INET,SOCK_STREAM,0);
    如果(socket_desc == -1)
    {
        的printf(无法创建套接字);
    }
    看跌期权(插座创建);    // prepare的SOCKADDR_IN结构
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(3000);    //绑定
    如果(绑定(socket_desc,(结构sockaddr *)及服务器的sizeof(服务器))小于0)
    {
        //打印错误信息
        PERROR(绑定失败错误。);
        返回1;
    }
    看跌期权(绑定完成);    //听
    听(socket_desc,3);    //接受并传入的连接
    看跌期权(等待进入连接...);
    C = sizeof的(结构SOCKADDR_IN);        C = sizeof的(结构SOCKADDR_IN);
       而(client_sock =接受(socket_desc,(结构sockaddr *)及客户端,(socklen_t的*)及c)项)
       {
        看跌期权(连接已接受);        的pthread_t sniffer_thread;
        new_sock = malloc的(1);
        * new_sock = client_sock;        如果(在pthread_create(安培; sniffer_thread,NULL connection_handler,(无效*)new_sock)℃的)
        {
            PERROR(无法创建线程);
            返回1;
        }        看跌期权(处理器分配);
    }    如果(client_sock℃,)
    {
        PERROR(接受失败);
        返回1;
    }
    返回0;
}
/ *
  这将处理每个客户端连接
  * /
无效* connection_handler(无效* socket_desc)
{
    //获取套接字描述符
    INT袜子= *为(int *)socket_desc;
    INT N;        焦炭sendBuff [100],client_message [2000];      而((N =的recv(袜子,client_message,2000,0))大于0)
      {        发送(袜子,client_message,N,0);
      }
      关闭(袜子);      如果(N == 0)
      {
        看跌期权(客户端断开连接);
      }
      其他
      {
        PERROR(recv的失败);
      }
    返回0;
}

客户:

 的#include<&stdio.h中GT;
#包括LT&;&string.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / socket.h中>
#包括LT&; netinet / in.h中>
#包括LT&; ARPA / inet.h>
#包括LT&;&stdlib.h中GT;
#包括LT&;&unistd.h中GT;#定义MAX_SIZE 50诠释的main()
{
    INT sock_desc;
    结构SOCKADDR_IN serv_addr;
    烧焦sbuff [MAX_SIZE],rbuff [MAX_SIZE];    如果((sock_desc =插座(AF_INET,SOCK_STREAM,0))小于0)
        的printf(无法创建套接字\\ n);    bzero((字符*)及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);    如果(连接(sock_desc,(结构sockaddr *)及serv_addr,sizeof的(serv_addr))小于0){
        的printf(无法连接到服务器\\ n);
        返回-1;
    }    的printf(成功连接 - 请输入字符串\\ n);
    而(与fgets(sbuff,MAX_SIZE,标准输入)!= NULL)
    {
      发送(sock_desc,sbuff,strlen的(sbuff),0);          如果(的recv(sock_desc,rbuff,MAX_SIZE,0)== 0)
           的printf(错误);
          其他
           的fputs(rbuff,标准输出);       bzero(rbuff,MAX_SIZE); //清除缓冲区 - > IMP否则previous单词字符也来了
    }
        关闭(sock_desc);
    返回0;}


解决方案

您可以使用线程创建多个客户端。创建为每个客户单独的线程,然后从线程处理器连接到服务器。我不知道这是一个很好的方法还是不行。

code:

 的#include<&stdio.h中GT;
#包括LT&;&string.h中GT;
#包括LT&; SYS / types.h中>
#包括LT&; SYS / socket.h中>
#包括LT&; netinet / in.h中>
#包括LT&; ARPA / inet.h>
#包括LT&;&stdlib.h中GT;
#包括LT&;&unistd.h中GT;#定义MAX_SIZE 50
#定义NUM_CLIENT 5
无效* connection_handler(无效* socket_desc);
诠释的main()
{
    INT socket_desc,new_socket,C,* new_sock,我;
    的pthread_t sniffer_thread;
    对于(i = 1; I< = NUM​​_CLIENT;我++){
        如果(在pthread_create(安培; sniffer_thread,NULL connection_handler,(无效*)ⅰ)℃的)
        {
            PERROR(无法创建线程);
            返回1;
        }
        睡眠(3);
    }
    了pthread_exit(NULL);
    返回0;
}无效* connection_handler(void *的主题ID)
{
    INT threadnum =(int)的主题ID;
    INT sock_desc;
    结构SOCKADDR_IN serv_addr;
    烧焦sbuff [MAX_SIZE],rbuff [MAX_SIZE];    如果((sock_desc =插座(AF_INET,SOCK_STREAM,0))小于0)
        的printf(无法创建套接字\\ n);    bzero((字符*)及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);    如果(连接(sock_desc,(结构sockaddr *)及serv_addr,sizeof的(serv_addr))小于0){
        的printf(无法连接到服务器\\ n);
    }    的printf(连接成功的客户端数:%d \\ n,threadnum);
    而(1)
    {
        的printf(螺纹数:%d \\ n,threadnum);
        与fgets(sbuff,MAX_SIZE,标准输入);
        发送(sock_desc,sbuff,strlen的(sbuff),0);        如果(的recv(sock_desc,rbuff,MAX_SIZE,0)== 0)
            的printf(错误);
        其他
           的fputs(rbuff,标准输出);        bzero(rbuff,MAX_SIZE);
        睡眠(2);
    }
    关闭(sock_desc);
    返回0;
}

有关理解的目的,我用睡眠

REF:

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

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

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

I have just started learning basic networking concepts.I am trying to implement a multithread server-client prog in C.but the problem is instead of running multiple windows/terminals/instances for clients,i should use fork() to create children of client.so by creating children of client multiple clients will be created.now each of these child clients will communicate with the server on a thread.

Earlier i created a similar prog but in that for multiple client you have to open multiple windows for clients and run all of them.

I am having trouble where to modify my code (both in server and client ones.I think server one is ok.but i am having no idea where to fork() in client program and what changes should be made).

Actually i don't want to open multiple windows to run multiple client,thats why i am using fork() to create multiple copies of it.Is there any other way by which i can create multiple clients and connect them to my server prog via threads.

Server :

// socket server example, handles multiple clients using threads

#include<stdio.h>
#include<string.h>    //strlen
#include<stdlib.h>    //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h>    //write
#include<pthread.h> //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;
}

Client:

#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

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;

}

解决方案

You can create multiple client using thread. Create separate thread for each client then from thread handler connect to server. I not sure it is a good way or not.

Code:

#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;
}

For understanding purpose i used sleep.

REF:

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

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

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

这篇关于用C多线程服务器/客户端的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆