zoukankan      html  css  js  c++  java
  • 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.
  • 相关阅读:
    sql server 操作文件
    sql server T-sql查询执行顺序
    js 时间相关函数
    js页面 :函数名 is not defined
    C# 通过文件路径获取文件名
    WRAR下载及注册
    Java 中xml解析
    string 与 byte[] 互转时的注意事项
    Spring MVC表单标签
    java 中基本类型与字符串之间的互相转换
  • 原文地址:https://www.cnblogs.com/gaojian/p/2620964.html
Copyright © 2011-2022 走看看