LINUX 并发服务器 fork

来源:互联网 发布:今日股市数据 编辑:程序博客网 时间:2024/05/19 03:16
/***************************************************************************** 
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);
}
原创粉丝点击