多进程TCP服务器--C/C++实现

        TCP多进程并发服务器的思想是每一个客户端的请求并不直接由服务器直接处理,而是由服务器创建一个子进程来处理

        基本流程:

                while(1){

                        int connfd=accept();

                        if(fork()==0){

                                close(sockfd);

                                fun();

                                close(connfd);

                                exit(0);

                            }

                        close(connfd);

                }

         服务端代码:tcpForkServer.cpp

#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string>
#include<cstring>
#include<unistd.h>
#include<errno.h>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>

using namespace std;
int main(int argc,char * argv[]){
    //创建套接字
    int sockFd=socket(AF_INET,SOCK_STREAM,0);
    if(sockFd<0)
     {
        puts("Create socket failed!");
        return -1;
     }
    //设置地址信息
    sockaddr_in saddr,raddr;
    int size=sizeof(saddr);
    saddr.sin_family=AF_INET;
    saddr.sin_addr.s_addr=inet_addr(argv[1]);
    saddr.sin_port=htons(atoi(argv[2]));
    //设置端口复用
    char on=1;
    setsockopt(sockFd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
    //绑定
    int ret=bind(sockFd,(sockaddr*)&saddr,size);
    if(ret==-1){
        puts("Bind failed!");
        return -1;
    }
    //监听
    ret=listen(sockFd,5);
    if(ret<0){
        puts("Listen failed");
        return -1;
    }
    //主进程循环等待客户端连接
    while(1){
            char cli_ip[INET_ADDRSTRLEN]={0};
            puts("Father process is waiting client....");

            int newFd=accept(sockFd,(sockaddr*)&raddr,(socklen_t*)&size);
            if(newFd<0){
                puts("Accept failed");
            }
            pid_t pid=fork();

            if(pid<0){
                perror("fork");
                _exit(0);
            }
            else if(pid==0){
                close(sockFd);
                char rbuf[1024]={0};
                int recv_len=0;
                //打印客户端的IP地址和端口号
                memset(cli_ip,0,sizeof(cli_ip));
                inet_ntop(AF_INET,&raddr.sin_addr,cli_ip,INET_ADDRSTRLEN);

                printf("-----------------\n");
                printf("client ip=%s ,port=%d \n",cli_ip,ntohs(raddr.sin_port));
                //循环接收信息
                while(1){
                    recv_len=recv(newFd,rbuf,sizeof(rbuf),0);
                     if(recv_len<0)
                       break;
                    printf("Recv buf(%s)\n",rbuf);
                    send(newFd,rbuf,recv_len,0);
                }
                printf("client_port %d closed! \n",ntohs(raddr.sin_port));
                close(newFd);
                exit(0);
            }
            else if(pid>0)
                close(newFd);
    }
    close(sockFd);
    return 0;
}

        客户端代码:tcpClient.cpp

#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<unistd.h>
#include<errno.h>
#include<iostream>
#include<stdio.h>
#include<stdlib.h>

using namespace std;

int main(int argc,char *argv[]){
    int sockFd=socket(AF_INET,SOCK_STREAM,0);
    if(sockFd<0){
        puts("Create socket failed!");
        return -1;
    }
    sockaddr_in saddr;
    int size=sizeof(sockaddr_in);
    saddr.sin_family=AF_INET;
    saddr.sin_addr.s_addr=inet_addr(argv[1]);
    saddr.sin_port=htons(atoi(argv[2]));

    char on=1;
    setsockopt(sockFd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));

    int ret=connect(sockFd,(sockaddr*)&saddr,size);
    if(ret<0){
        puts("Connect Failed!");
        return -1;
    }
    
    int val=sizeof(sockaddr);
    char rbuf[50],sbuf[100];
    while(1){
        puts("Please enter data:");
        scanf("%s",sbuf,sizeof(sbuf));
        ret=sendto(sockFd,sbuf,strlen(sbuf),0,
                        (sockaddr*)&saddr,val);
        if(ret<0){
            perror("send failed!");
        }

        ret=recv(sockFd,rbuf,sizeof(rbuf),0);
        if(ret<0){
            perror("recv failed");
        }
        printf("server reply: %s\n",rbuf);
        memset(rbuf,0,sizeof(rbuf));
        memset(sbuf,0,sizeof(sbuf));
    }
    close(sockFd);
    return 0;
}

         运行结果:服务端可以看见客户端的IP地址相同但端口号不同说明是三条连接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wpromise_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值