UNIX网络编程——为每个客户现场分派一个线程(简单示例参考)

#include<stdio.h> 
#include<sys/types.h> 
#include<sys/socket.h> 
#include<unistd.h> 
#include<stdlib.h>
#include<pthread.h>
#include<errno.h> 
#include<arpa/inet.h> 
#include<netinet/in.h> 
#include<string.h> 
#include<signal.h> 
           
#define ERR_EXIT(m)  do{perror(m);exit(EXIT_FAILURE);}while (0) 

#define LENGTH_OF_LISTEN_QUEUE 20
#define BUFFER_SIZE 1000

//pthread_metux_t mlock = PTHREAD_METUX_INITIALIZER; 
int main(void)
{
	int servfd;
	struct  sockaddr_in servaddr;
        void *doit(void *);	 
	if ((servfd = socket(AF_INET,SOCK_STREAM,0)) < 0)  
	{  
	    //建立Socket,程序调用Socket函数,该函数返回一个类似于文件描述符的句柄  
	    printf("create socket error!\n");  
	    exit(1);  
	}  
	//sin_zero用来将sockaddr_in结构填充到与struct sockaddr同样的长度,可以用bzero()或memset()函数将其置为零  
	bzero(&servaddr,sizeof(servaddr));  
	servaddr.sin_family = AF_INET;  
	servaddr.sin_port = htons(9999);  
	servaddr.sin_addr.s_addr = htons(INADDR_ANY);/*系统自动填入本机IP地址 */  
	int on =1;
	if(setsockopt(servfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0)
	 ERR_EXIT("setsockopt error");
	if (bind(servfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)  
	{  
	    //服务端通过调用 bind函数来配置本地信息。Bind函数将socket与本机上的一个端口相关联,随后你就可以在该端口监听服务请求。  
	    printf("bind to port %d failure!\n",9999);  
	    exit(1);  
	}  

	if (listen(servfd, LENGTH_OF_LISTEN_QUEUE) < 0)  
	{  
	   //Listen函数使socket处于被动的监听模式,并为该socket建立一个输入数据队列,将到达的服务请求保存在此队列中,直到程序处理它们。  
	       printf("call listen failure!\n");  
	       exit(1);  
	} 
	struct sockaddr_in cliaddr;
	socklen_t clilen = sizeof(cliaddr);//
	//cliaddr = Malloc(clilen);//为保留客户端address开辟空间
	int clientfd; 
	while(1)
	{  
	    //服务一直在运行,直到被某个操作或命令终止该进程  
	    //accept()函数让服务器接收客户的连接请求  
	    if((clientfd = accept(servfd, (struct sockaddr *)&cliaddr, &clilen)) < 0)
	{
		 if(errno == EINTR)
		   continue;
		  else
		   ERR_EXIT("accept error");
	}
	printf("recv connect ip = %s port = %d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));
	      
	    // 创建用于处理新连接的子线程  
	    pthread_t tid ;  //
	    pthread_create(&tid, NULL, &doit, (void*)clientfd);  

	}
}

	void* doit (void* arg)
	{  
	// 分离线程,使主线程不必等待此线程  
	pthread_detach(pthread_self()); 
	int recvBytes = 0;  
	char recvBuf[BUFFER_SIZE]; 

	while(1)  
	{  
            memset(recvBuf, 0, BUFFER_SIZE);  
	    if ((recvBytes=recv((int) arg, recvBuf, BUFFER_SIZE, 0)) <= 0)   
	    {  
		perror("recv出错!\n");  
		return NULL;  
	    }  
	    recvBuf[recvBytes]='\0';  
	    printf("recvBuf:%s\n", recvBuf);  
            send((int) arg, recvBuf, sizeof(recvBuf), 0);
	}  

	close((int) arg);  
	return NULL;  
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值