繁体   English   中英

从C中的套接字频繁进行读/写操作

[英]Frequent read/write operation from socket in C

我想在C中为服务器编写一个脚本(套接字编程),该脚本将以侦听模式存在,并读取客户端的HTTP请求并对该请求执行一些操作。

例如:假设我收到的请求如下:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><line2:connectionClearedEvent><cause>normalClearing</cause></line2:connectionClearedEvent></SOAP-ENV:Body></SOAP-ENV:Envelope>

我想检查一下,如果请求中有“ connectionClearedEvent ”字符串,然后将计数器加1。

问题:

第一个想法假设服务器上有负载,如果完成了将所有请求从套接字写入文件的操作,则由于频繁的写入操作,它会跳过一些请求。

第二个想法假设服务器上有负载,如果实现是只读取传入的请求并搜索该关键字,那么由于频繁的读取操作,它会跳过某些请求。

在有大量请求发送到服务器时,任何人都可以建议一种方法来执行上述操作。

编辑:相同connection_handler()的代码将处理每个客户端的连接,但是我现在面临的问题是处理文件。

 #include<stdio.h> #include<string.h> //strlen #include<stdlib.h> //strlen #include<sys/socket.h> #include<arpa/inet.h> //inet_addr #include<unistd.h> //write #include<pthread.h> //for threading , link with lpthread //the thread function void *connection_handler(void *); int main(int argc , char *argv[]) { printf("Program name %s\\n", argv[0]); if( argc == 2 ) { printf("The argument supplied is %s\\n", argv[1]); } else if( argc > 2 ) { printf("Too many arguments supplied.\\n"); } else { printf("Server Port not provided..exiting \\n"); // scanf("%s",&argv[1]); return 1; } int socket_desc , client_sock , c , *new_sock; struct sockaddr_in server , client; //Create socket socket_desc = socket(AF_INET , SOCK_STREAM , 0); if (socket_desc == -1) { printf("Could not create socket"); } puts("Socket created"); //Prepare the sockaddr_in structure server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons(atoi(argv[1])); //Bind if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) { //print the error message perror("bind failed. Error"); return 1; } puts("bind done"); //Listen listen(socket_desc , 3); //Accept and incoming connection puts("Waiting for incoming connections..."); c = sizeof(struct sockaddr_in); //Accept and incoming connection puts("Waiting for incoming connections..."); c = sizeof(struct sockaddr_in); while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ) { puts("Connection accepted"); pthread_t sniffer_thread; new_sock = malloc(1); *new_sock = client_sock; if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0) { perror("could not create thread"); return 1; } //Now join the thread , so that we dont terminate before the thread //pthread_join( sniffer_thread , NULL); puts("Handler assigned"); } if (client_sock < 0) { perror("accept failed"); return 1; } return 0; } /* * This will handle connection for each client * */ void *connection_handler(void *socket_desc) { //Get the socket descriptor int sock = *(int*)socket_desc; int read_size; char *message , client_message[2000]; static char* ok_response = "HTTP/1.1 200 OK\\r\\n" "Content-Length: 101\\r\\n" "Content-type: text/xml; charset=utf-8\\r\\n" "\\r\\n" "<html>\\n" " <body>\\n" " <h1>Bad Request</h1>\\n" " <p>This server understand your request.</p>\\n" " </body>\\n" "</html>\\n"; static char* body = "<html>\\n" " <body>\\n" " <h1>Bad Request</h1>\\n" " <p>This server understand your request.</p>\\n" " </body>\\n" "</html>\\n"; printf("content length : %d\\n",strlen(body)); //Receive a message from client while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 ) { //Send the message back to client puts(client_message); write(sock , ok_response , strlen(ok_response)); memset (client_message,'\\0',2000); } if(read_size == 0) { puts("Client disconnected"); fflush(stdout); } else if(read_size == -1) { perror("recv failed"); } //Free the socket pointer free(socket_desc); return 0; } 

这里有三件事要做(可以合并):

  1. 增加侦听队列( listen(socket, <number of pending requests>) )-这将有助于处理突发请求,但是如果您不能足够快地处理请求,则最终也会失败

  2. 将您的工作负载分散在许多工作人员上 ,以利用现代的多线程和多处理环境。 这可以通过线程或进程来完成,其中对于每个请求,在accept传入的连接之后,将新的连接套接字提供给工作线程/进程进行处理。 这样,您在处理请求时不会阻塞侦听套接字。 同样,这只能扩展到最大程度,因为如果服务器超载,您最终将耗尽工作人员。

  3. 群集 -最终,单个服务器/计算机可能无法处理传入的负载。 您需要创建一种负载平衡机制,并将请求转移到其他计算机上进行处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM