Linux下多线程并发服务器的简单实现

Linux下多线程并发服务器的简单实现

pthread_server.c

#include <stdio.h>
#include <sys/types.h>	       
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include <pthread.h>

#define Max 1024
#define Error -1

static int sfd = 0;
const ushort port = 49999;
//服务器的初始化
int init_server()
{
	//建立流式套接字
	sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd < 0){
		perror("socket");
		goto SET_ERR;
	}
	//服务端的地址结构(ipv4)
	//htons进行大小端转化
	//INADDR_ANY表示任意ip地址,系统提供的宏
	struct sockaddr_in server_addr  = {
				    	.sin_family = AF_INET,
					 	.sin_port   = htons(port),
						.sin_addr   = {
						.s_addr     = htonl(INADDR_ANY),
						},
	};
	//绑定地址
	if(bind(sfd,(struct sockaddr*)&server_addr,sizeof(server_addr))<0){
		perror("bind");
		goto SET_ERR;
	}
	//设置监听套接字,允许最大连接的套接字
	if(listen(sfd,10) < 0){
		perror("listen");
		goto SET_ERR;
	}
	return sfd;
SET_ERR:
	close(sfd);
	return Error;

}

//接收客户端的数据进行处理
void *reply_client(void *arg)
{
	//循环接收数据
	while(1){
		char buf[Max] = {0};
		memset(buf,0,sizeof(buf));
		//arg参数是一个void*类型,这里进行类型转换
		//有的读者可能会奇怪,这里为什么写的是(int)(long)arg
		//笔者这里采用的是64位的Linux系统,直接写(int)arg,看上去没有什么问题,
		//进行数据类型转换,但是系统会提示一个警告,精度的丢失,在64位操作系统下面
		//指针类型是8位,int类型是4位,会提示精度丢失,所以为了去掉该警告,先转换成
		//long类型(64位下是8字节),如果采用的是32位操作系统,可以直接(int)arg
		size_t nByte = recv((int)(long)arg,buf,sizeof(buf),0);
		if(nByte < 0){
			perror("recv");
			return (void *)Error;
		}else if(nByte == 0){
			printf("the client is disconnect...\n");
			close((int)(long)arg);
			pthread_exit((void*)0);//退出
		}else{
			printf("%s\n",buf);
		}
	}	
}

int main(int argc, const char *argv[])
{
	int fd = init_server();
	struct sockaddr_in clinet_addr;
	int len = sizeof(clinet_addr);
	printf("waiting for connect...\n");
	int cfd;
	while(1){
		//客户端连接
		cfd = accept(fd,(struct sockaddr*)&clinet_addr,&len);
		if(cfd < 0){
			perror("accept");
			return Error;
		}
		printf("the client ip is %s\n",inet_ntoa(clinet_addr.sin_addr));
		pthread_t tid;
		//没连接一个客户端,就创建一个线程来处理客户端的数据
		pthread_create(&tid,NULL,reply_client,(void *)(long)cfd);
		pthread_detach(tid);//线程分离,用于回收线程
		//pthread_join()也可用于线程的回收
	}
	
	return 0;
SET_ERR:
	close(fd);
	return Error;
}

编译执行:

gcc pthread_server.c -lpthread -o s (-lpthread表示连接线程库,这一步不能丢)

执行效果如下:(这里的客户端采用的是网络调试助手来进行模拟的,不需要自己实现)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值