网络编程(15)—— 实现利用管道保存客户端数据的socket服务端

        本文紧接着上一文,创建了一个socket回声多进程服务端,并另启子进程利用管道pipe将客户端传递过来的数据保存到本地。代码如下,稍后对关键点进行解析。

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

#define BUF_SIZE 30

void error_handling(char* message);
void read_childproc(int sig);
int main(int argc,char* argv[])
{
    struct sigaction act;
    int state;
    int servSock,clntSock;
    int adrSize;
    pid_t pid;
    int strLen;
    int fds[2];
    struct sockaddr_in servAddr,clntAddr;
    char buf[BUF_SIZE];
    if(argc!=2)
    {
        printf("Usage %s \n",argv[0]);
        exit(1);
    }
    
    act.sa_handler=read_childproc;
    sigemptyset(&act.sa_mask);
    act.sa_flags=0;
    state=sigaction(SIGCHLD,&act,0);
    //创建socket
    servSock=socket(AF_INET,SOCK_STREAM,0);

    //创建地址
    servAddr.sin_family=AF_INET;
    servAddr.sin_addr.s_addr=htonl(INADDR_ANY);
    servAddr.sin_port=htons(atoi(argv[1]));
    
    //进行地址的binding
    if(bind(servSock,(struct sockaddr*)&servAddr,sizeof(servAddr))==-1)
        error_handling("bind() error");
    
    //开启监听
    if(listen(servSock,5)==-1)
            error_handling("listen error");

    //创建管道
    pipe(fds);
    pid=fork();
    if(pid==0)
    {
        FILE* fp=fopen("message.txt","a");
        int i;
        int len;
        if(fp==NULL)
        {
            return 0;
        }
        for(i=0;i<10;i++)
        {
            len=read(fds[0],buf,BUF_SIZE);
            fwrite(buf,1,len,fp);
            printf("保存客户端第%d次数据\n",i+1);
        }
        fclose(fp);
        return 0;
    }
    //接收客户端连接
    while(1)
    {
        adrSize=sizeof(clntAddr);
        clntSock=accept(servSock,(struct sockaddr*)&clntAddr,&adrSize);
        if(clntSock==-1)
            continue;
        else
            puts("new client connected ...");

        pid=fork();
        if(pid==-1)
        {
            close(clntSock);
            continue;
        }
        if(pid==0)
        {
            close(servSock);
            while((strLen=read(clntSock,buf,BUF_SIZE))!=0)
            {
                write(fds[1],buf,strLen);
                write(clntSock,buf,strLen);
            }
            close(clntSock);
            puts("client disconnected ...");
            return 0;
        }
        else
        {
            close(clntSock);
        }
    }
    close(servSock);
    return 0;
}



void read_childproc(int sig)
{
    pid_t pid;
    int status;
    pid=waitpid(-1,&status,WNOHANG);
    printf("removed proc id:%d \n",pid);
}


void error_handling(char* message)
{
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}
第52行,利用pipe()创建了管道,用于读写。

第53行,创建子进程,然后在子进程中打开文本文件,读取管道的读端,然后将信息写入到文档中。

第82行,每连接一个客户端就启动一个子进程,然后在子进程中93行处将客户端传送过来的内容写到管道的写端中。

网络编程(15)—— 实现利用管道保存客户端数据的socket服务端_第1张图片


Github位置:

https://github.com/HymanLiuTS/NetDevelopment

克隆本项目:

git clone [email protected]:HymanLiuTS/NetDevelopment.git

获取本文源代码:

git checkout NL15


你可能感兴趣的:(网络通信编程,网络通信编程)