基本信息
源码名称:高性能服务器代码(50_06th_server_threads.c)
源码大小:2.56KB
文件格式:.c
开发语言:C/C++
更新时间:2020-10-29
   友情提示:(无需注册或充值,赞助后即可获取资源下载链接)

     嘿,亲!知识可是无价之宝呢,但咱这精心整理的资料也耗费了不少心血呀。小小地破费一下,绝对物超所值哦!如有下载和支付问题,请联系我们QQ(微信同号):813200300

本次赞助数额为: 2 元 
   源码介绍
I/O复用   一个客户端一个线程

/** I/O复用   一个客户端一个线程
 *
 *  gcc -o 50_06th_server_threads 50_06th_server_threads.c -lpthread
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>

#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>			/* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>

void *task_client(void *arg) {
	int clientfd = *(int *)arg;
	char buf[1024];

    printf("this is a new thread, you got connected %d\n", clientfd);

	pthread_detach(pthread_self()); //标记为DETACHED状态,完成后释放自己占用的资源。
	
	while (1) {
		if (recv(clientfd, buf, sizeof(buf)-1, 0) > 0) {  //MSG_OOB
		
		} else {
			perror("recv");
			break;
		}		

		printf("Received a message : %s\n", buf);
	}

	printf("this is over \n");
}

int main(int argc, char *argv[]) { 
    struct sockaddr_in addr;
    int nb_connection = 5;

    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd == -1) {
        return -1;
    }

    int on = 1; //允许重复使用本地地址与套接字进行绑定
    setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(int));

    addr.sin_family = AF_INET;
    addr.sin_port = htons(5050);
	addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //addr.sin_addr.s_addr = inet_addr("192.168.3.130");
    bzero(&(addr.sin_zero), 8);

    if (bind(listenfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
        close(listenfd);
        return -1;
    }

    if (listen(listenfd, nb_connection) == -1) {
        close(listenfd);
        return -1;
    }


	/* Set the socket to blocking, this is essential in event
	 * server socket is blocking. */
	int flags = fcntl(listenfd, F_GETFL, 0);
	if (flags < 0 || fcntl(listenfd, F_SETFL, flags & ~O_NONBLOCK) < 0) {
		close(listenfd);
		return -1;
	}

	int clientfd;
    struct sockaddr_in client_addr;
	socklen_t client_addrlength = sizeof(struct sockaddr_in);

	pthread_t pthread_tid;
	uint8_t index_tid = 0;
	
    while (1) {   
		if ((clientfd = accept(listenfd, (struct sockaddr *)&client_addr, &client_addrlength)) != -1) {
			printf("TCP-%d got a connection from %s\n", index_tid, inet_ntoa(client_addr.sin_addr));
			
			pthread_create(&pthread_tid, NULL, &task_client, (void *)&clientfd);
		}

		if (errno == EAGAIN) { //在没有等待处理的连接请求时,errno值等于 EAGAIN
			printf("resource temporarily unavailable \n");
			sleep(1);
		} else {
			perror("accept");
		}	
    }

	close(listenfd);

    return -1;
}