LINUX 并发服务器 fork

本文介绍了一种使用双Socket的TCP服务端实现方法,该服务端能够同时处理多个客户端的连接请求,并通过创建子进程的方式为每个客户端提供独立的服务。一方面接收客户端数据,另一方面向客户端发送回应。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/***************************************************************************** 
File name:      tcp_server_fork 
Description:    tcp服务端,可接受来自100个客户端的连接请求,每个客户端会创建一
                个进程,在主函数中创建了两个socket,一个用于接收,另一个用于发
送 
Author:         作者 
Version:        版本  
Date:           2012.2.22
Input:          服务器向客户端发送的数据 send
                存储客户端发来的数据指针 recv
Output:        无
History:        
*****************************************************************************/ 
#include <stdlib.h> 
#include <stdio.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <netinet/in.h> 
#include <sys/socket.h> 


#define MY_PORT_RECV 3333 //服务器接收端口
#define MY_PORT_SEND 4444 //服务器发送端口
                                       
void tcp_server(char *recv,char *send)
{
int listen_fd1,accept_fd1,listen_fd2,accept_fd2;
struct sockaddr_in client_addr1,server_addr1,client_addr2,server_addr2;
int n;
int nbytes;
    int sin_size;
    /*创建 scoket1 用于接收客户端信息*/
  if((listen_fd1=socket(AF_INET,SOCK_STREAM,0))<0)
  {
        printf("Socket Error:%s\n\a",strerror(errno));
        exit(1);
  }
    /*填充server1的 ip 端口 协议类型用于接收*/
  bzero(&server_addr1,sizeof(struct sockaddr_in));
bzero(&server_addr2,sizeof(struct sockaddr_in));
  server_addr1.sin_family=AF_INET;
  server_addr1.sin_port=htons(MY_PORT_RECV);
  server_addr1.sin_addr.s_addr=htonl(INADDR_ANY);
 
n=1;
 
  /* 如果服务器终止后,服务器可以第二次快速启动而不用等待一段时间  */
  setsockopt(listen_fd1,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(int));
    /*将server1的信息绑定到socket1的描述符*/
  if(bind(listen_fd1,(struct sockaddr *)&server_addr1,sizeof(server_addr1))<0)    
  {
        printf("Bind Error:%s\n\a",strerror(errno));
        exit(1);
  }
    /*监听*/
  listen(listen_fd1,100); 


/*创建 scoket1 用于向客户端发送信息*/
    if((listen_fd2=socket(AF_INET,SOCK_STREAM,0))<0)
  {
        printf("Socket Error:%s\n\a",strerror(errno));
        exit(1);
  }
    /*填充server2的 ip 端口 协议类型用于发送*/
  server_addr2.sin_family=AF_INET;
  server_addr2.sin_port=htons(MY_PORT_SEND);
  server_addr2.sin_addr.s_addr=htonl(INADDR_ANY);
 
  /* 如果服务器终止后,服务器可以第二次快速启动而不用等待一段时间  */
  setsockopt(listen_fd2,SOL_SOCKET,SO_REUSEADDR,&n,sizeof(int));
    /*将server2的信息绑定到socket2的描述符*/
  if(bind(listen_fd2,(struct sockaddr *)&server_addr2,sizeof(server_addr2))<0)    
  {
        printf("Bind Error:%s\n\a",strerror(errno));
        exit(1);
  }
    /*监听*/
  listen(listen_fd2,100);                                                      
  while(1)
  {
/*等待客户端的连接,accept函数阻塞*/
    accept_fd1=accept(listen_fd1,(struct sockaddr *)(&client_addr1),&sin_size);  
    if((accept_fd1<0)&&(errno==EINTR))                                       
          continue; 
    else if(accept_fd1<0)
    {
        printf("Accept Error:%s\n\a",strerror(errno));
        continue;
        }
        /*创建子进程 来处理客户端连接接收信息*/
  if((n=fork())==0)                          
    {    
char str_recv[1024];

            /*读取来自客户端的数据*/
            if((nbytes=read(accept_fd1,str_recv,1024))==-1) 

fprintf(stderr,"Read Error:%s\n",strerror(errno)); 
exit(1); 
}
str_recv[nbytes]='\0';
recv=str_recv;
/*打印出客户端IP*/
            fprintf(stderr,"Server get connection (recv) from %s\n",inet_ntoa(client_addr1.sin_addr));
            /*打印出接收到的字符串*/
printf("Server received %s\n",str_recv);
   /*关闭socket*/


            close(accept_fd1);
/*退出子进程*/
exit(0);
        } 
/*等待来自4444端口的连接*/
        accept_fd2=accept(listen_fd2,(struct sockaddr *)(&client_addr2),&sin_size);  
    if((accept_fd2<0)&&(errno==EINTR))                                        //阻塞在此
          continue; 
    else if(accept_fd2<0)
    {
        printf("Accept Error:%s\n\a",strerror(errno));
        continue;
        }
/*创建子进程用于发送数据到客户端*/
        if((n=fork())==0)
        {       
            char *str_send=send;
            /*打印出客户端IP*/            
            printf("Server get connection (send) from %s\n",inet_ntoa(client_addr2.sin_addr));
            /*发送信息*/
            write(accept_fd2,str_send,strlen(str_send));
            printf("send to client :%s\n",str_send);      
    }
    //close(accept_fd);     
}



int main(void)
{
char *str1="hello";
char *str2;
    str2=(char *)malloc(1024);
    tcp_server(str2,str1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值