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

时间:2023-03-08 16:38:58
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编程的知识点几本全部说清楚了,后面需要在实践项目中不断的使用,巩固能力。