Linux下的C Socket编程 -- server端的继续研究

Linux下的C Socket编程(四)

延长server的生命周期

在前面的一个个例子中,server在处理完一个连接后便会立即结束掉自己,然而这种server并不科学啊,server应该是能够一直接受处理连接的,知道结束命令结束掉server。

实现这种情况的最简单的方法便是将accept()放置在一个死循环中,使得它能够一直的接受新的连接。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<netinet/in.h>

int main() {
	int socket_desc, new_socket;
	struct sockaddr_in server, client;
	char *message;
	
	socket_desc = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == socket_desc) {
		perror("cannot create socket");
		exit(1);
	}
	
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_family = AF_INET;
	server.sin_port = htons(8888);
	
	if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {
		perror("cannot bind socket");
		exit(1);
	}
	
	puts("bind success");
	
	listen(socket_desc, 5);
	puts("waiting for incoing connections...");
	
	socklen_t client_len = sizeof(client);
	while((new_socket = accept(socket_desc, (struct sockaddr *)&client, &client_len))) {
		puts("accept success");
		
		message = "hello world";
		send(new_socket, message, strlen(message), 0);
	}
	
	if (new_socket < 0) {
		perror("accept error");
		exit(1);
	}
	
	close(new_socket);
	close(socket_desc);
	
	return 0;
}

再次运行代码,向server发起多个请求,server都能够接受到,不信可以自己试试呦~

到现在为止,server端的全部功能都已经全部的实现,然而实现的这个server比较鸡肋,他每次只能处理一个请求,当多个请求来临时当前的请求就会阻塞掉后面的请求,直到当前的请求处理完成。

所以现在我们应该想办法让她能够同时处理多个连接了。

多线程处理多个连接

为了处理每一个连接请求,我们都需要为她们单独的运行一份代码,我们需要使得一份代码能够单独的运行,实现这种功能的方法有很多,这里就暂且说说多线程的方法。

当主程序接收到新的连接后,会创建一个新的线程去处理这个连接的事务,之后主程序会回去继续接受新的连接。

在Linux中我们可以使用pthread(posix threads)库来使用多线程。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<netinet/in.h>

void *connection_handler(void *);

int main() {
	int socket_desc, new_socket, *thread_socket;
	struct sockaddr_in server,client;
	socklen_t client_len;
	char *message;
	
	socket_desc = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == socket_desc) {
		perror("cannot create socket");
		exit(EXIT_FAILURE);
	}
	
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons(8888);
	
	if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {
		perror("bind failed");
		exit(EXIT_FAILURE);
	}
	puts("bind success");
	
	listen(socket_desc, 5);
	puts("waiting for incoming connections...");
	
	client_len = sizeof(client);
	while((new_socket = accept(socket_desc, (struct sockaddr *)&client, &client_len))) {
		puts("connection accepted");
		
		message = "Hello Client, now i will assign a handler for you\r\n";
		
		send(new_socket, message, strlen(message), 0);
		
		pthread_t sniffer_thread;
		*thread_socket = new_socket;
		
		if (pthread_create(&sniffer_thread, NULL, connection_handler, (void *)thread_socket) < 0) {
			perror("cannot create thread");
			exit(EXIT_FAILURE);
		}
		
		puts(Handler assigned);
	}
	
	if (new_socket < 0) {
		perror("accept failed");
		exit(EXIT_FAILURE);
	}
	
	return 0;
	
}

void *connection_handler(void *socket_desc) {
	int socket = *(int *)socket_desc;
	char *message;
	
	message = "Into connection handler\r\n";
	send(socket, message, strlen(message), 0);
	
	message = "communicate with client\r\n";
	send(socket, message, strlen(message), 0);
	
	return 0;
}

OK,到现在基本的socket编程的知识点几本全部说清楚了,后面需要在实践项目中不断的使用,巩固能力。

posted @ 2017-01-07 18:16  听雨阁中听雨歌  Views(481)  Comments(0Edit  收藏  举报