socket通信,server与多客户端通信(二)

简介:
接上回,socket通信,server与多客户端通信的文章。

搞一个先fork一堆子进程出来,再一起监听的server,client程序不变。

复制代码
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/signal.h>
#include<sys/wait.h>

#define HELLO_WORLD_SERVER_PORT    6666
#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1024

void reaper(int sig){
int status;
while(    wait3(&status,WNOHANG,(struct rusage*)0)  >=0   )
        ;
}

int main(int argc, char **argv){
    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);
    server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);

    int server_socket = socket(AF_INET,SOCK_STREAM,0);
    if( server_socket < 0){
        printf("Create Socket Failed!");
        exit(1);
    }

    if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))){
        printf("Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT);
        exit(1);
    }

    fprintf(stderr,"Before Main Process listen.\n");

    if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) ){
        printf("Server Listen Failed!");
        exit(1);
    }
    fprintf(stderr, "After Main Process listen.\n");

(void)signal(SIGCHLD,reaper);
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr);

int procnt;
for (procnt=0; procnt<10; procnt++){
        int child_process_pid = fork(); 
        if(child_process_pid == 0 ){
           fprintf(stderr,"Child %d is born",getpid());
           fprintf(stderr,"Before accept. In %d.\n",getpid());

           int new_server_socket = 
             accept(server_socket,(struct sockaddr*)&client_addr,&length);
           if ( new_server_socket < 0){
              printf("Server Child Accept Failed!\n");
              break;
           }
           fprintf(stderr,"After accept. In %d.\n",getpid());
           close(server_socket);

           char buffer[BUFFER_SIZE];
           bzero(buffer, BUFFER_SIZE);
           strcpy(buffer,"Hello,World! FromServer! ");

           int pd;
           pd=getpid();
           char cpd[10];
           sprintf(cpd,"%d",pd);
           strcat(buffer,cpd);
           strcat(buffer,"\n");            
           send(new_server_socket,buffer,BUFFER_SIZE,0);
           bzero(buffer,BUFFER_SIZE);

           length = recv(new_server_socket,buffer,BUFFER_SIZE,0);
           if (length < 0){
                printf("Server Recieve Data Failed!\n");
                exit(1);
           }
           fprintf(stderr,"got: %s in %d\n",buffer,getpid());

           //I should put here some rest dealings 
           //for current child process instead.
           //I will add it later.
           close(new_server_socket);
           exit(0);
      }else{
           //do nothing
      }
}

for(;;){
    sleep(10);
    fprintf(stderr,"I am main process waked from sleep.\n");
}

close(server_socket);
return 0;
}
复制代码
这样,client 和 server的通信,实际上就是server里面一群子进程在监听。谁逮住了谁响应。当然,这个进程池尚且有差距。今后再改进,考虑一次服务结束后,如何休眠和唤醒。

为了看着方便,把client的程序也放在这里:

复制代码
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define HELLO_WORLD_SERVER_PORT    6666
#define BUFFER_SIZE 1024

void talk_to_server(char ** argv)
{   
    struct sockaddr_in client_addr;
    bzero(&client_addr,sizeof(client_addr));
    client_addr.sin_family = AF_INET;
    client_addr.sin_addr.s_addr = htons(INADDR_ANY);
    client_addr.sin_port = htons(0);

    int client_socket = socket(AF_INET,SOCK_STREAM,0);
    if( client_socket < 0){
        printf("Create Socket Failed!\n");
        exit(1);
    }
    
    if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr))){
        printf("Client Bind Port Failed!\n");
        exit(1);
    }

    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(server_addr));
    server_addr.sin_family = AF_INET;

    if(inet_aton(argv[1],&server_addr.sin_addr) == 0){
        printf("Server IP Address Error!\n");
        exit(1);
    }
    server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
    socklen_t server_addr_length = sizeof(server_addr);

    if( 
      connect( client_socket, (struct sockaddr*)&server_addr, 
          server_addr_length) < 0){
        printf("Can Not Connect To %s!\n",argv[1]);
        exit(1);
    }

    char buffer[BUFFER_SIZE];
    bzero(buffer,BUFFER_SIZE);

    int length = recv(  client_socket,  buffer,BUFFER_SIZE,0);

    if(length < 0){
        printf("Recieve Data From Server %s Failed!\n", argv[1]);
        exit(1);
    }
    printf("From Server %s :\t%s",argv[1],buffer);

    bzero(buffer,BUFFER_SIZE);
    char name[64];
    gethostname(name,sizeof(name));
    strcpy(buffer,name);

    send(client_socket,buffer,BUFFER_SIZE,0);
    close(client_socket);
}

int main(int argc, char **argv)
{
    if (argc != 2){
        printf("Usage: ./%s ServerIPAddress\n",argv[0]);
        exit(1);
    }

    int i=0;
    for(i=0; i<10000; i++){
        talk_to_server(argv);
        sleep(10);
    }
    return 0;
}
复制代码
server端运行结果如下:

复制代码
Before Main Process listen.
After Main Process listen.

Child 3882 is bornBefore accept. In 3882.
Child 3883 is bornBefore accept. In 3883.
Child 3884 is bornBefore accept. In 3884.
Child 3885 is bornBefore accept. In 3885.
Child 3886 is bornBefore accept. In 3886.
Child 3887 is bornBefore accept. In 3887.
Child 3888 is bornBefore accept. In 3888.
Child 3889 is bornBefore accept. In 3889.
Child 3890 is bornBefore accept. In 3890.
Child 3891 is bornBefore accept. In 3891.

I am mian process waked from sleep.
I am mian process waked from sleep.
I am mian process waked from sleep.

After accept. In 3882
got: post2.gao in 3882

After accept. In 3883
got: post2.gao in 3883

After accept. In 3884
got: post2.gao in 3884

After accept. In 3885
got: post2.gao in 3885

After accept. In 3886
got: post2.gao in 3886

After accept. In 3887
got: post2.gao in 3887

After accept. In 3888
got: post2.gao in 3888

After accept. In 3889
got: post2.gao in 3889

After accept. In 3890
got: post2.gao in 3890

After accept. In 3891
got: post2.gao in 3891


I am mian process waked from sleep.
I am mian process waked from sleep.
I am mian process waked from sleep.
I am mian process waked from sleep.
复制代码


本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/archive/2012/08/03/2620964.html,如需转载请自行联系原作者
目录
相关文章
|
29天前
|
Java
用java实现Client和Server之间的互相通信
本文介绍了如何使用Java实现客户端和服务器之间的通信,包括服务器端创建ServerSocket、接受客户端连接、读取和发送消息,以及客户端创建Socket连接、发送和接收消息的完整过程。
22 0
用java实现Client和Server之间的互相通信
|
6月前
【进程通信】用命名管道模拟server和client之间的通信
【进程通信】用命名管道模拟server和client之间的通信
|
6月前
|
前端开发 Java Maven
【Netty 网络通信】启动客户端连接服务端实现通信
【1月更文挑战第9天】【Netty 网络通信】启动客户端连接服务端实现通信
|
网络协议 Go API
php-websocket hyperf/websocket-server/client 客户端和服务器实时双向数据传输
php-websocket hyperf/websocket-server/client 客户端和服务器实时双向数据传输
337 0
|
网络协议 图形学
Unity【Socket TCP】- 服务端与客户端通讯的简单示例
Unity【Socket TCP】- 服务端与客户端通讯的简单示例
708 0
Unity【Socket TCP】- 服务端与客户端通讯的简单示例
|
网络协议 JavaScript Unix
nodejs TCP服务器和客户端通信的socket结构
这个结构我们大学时上Unix网络编程的专业课就学过了:
nodejs TCP服务器和客户端通信的socket结构
WebSocket连接里客户端和服务器端的Socket ID
WebSocket客户端和WebSocket服务器建立连接后,在WebSocket服务器端会为每一个新连接分配一个socket id,用于唯一标识这个连接。
WebSocket连接里客户端和服务器端的Socket ID
|
网络协议 JavaScript
nodejs TCP server和TCP client如何进行数据交互
nodejs TCP server和TCP client如何进行数据交互
248 0
nodejs TCP server和TCP client如何进行数据交互
|
网络协议
TCP服务器端和客户端建立连接 - 客户端的回调处理
TCP服务器端和客户端建立连接 - 客户端的回调处理
144 0
TCP服务器端和客户端建立连接 - 客户端的回调处理
|
网络协议
TCP服务器端和客户端建立连接 - 服务器端的回调处理
TCP服务器端和客户端建立连接 - 服务器端的回调处理
290 0
TCP服务器端和客户端建立连接 - 服务器端的回调处理