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
";
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
";
send(socket, message, strlen(message), 0);
message = "communicate with client
";
send(socket, message, strlen(message), 0);
return 0;
}
OK,到现在基本的socket编程的知识点几本全部说清楚了,后面需要在实践项目中不断的使用,巩固能力。