我正在尝试用C为自己构建一个网络应用程序。到目前为止,我已经让HTTP服务器正常工作,但由于某种原因,当我有需要其他CSS和JavaScript文件的HTML文件时,浏览器(Firefox)会非常快地处理多个请求,导致服务器和客户端之间的套接字连接损坏。我已经尝试了很多不同的方法来让HTTP服务器在不生成损坏的TCP连接的情况下工作。
目前,我有一个循环调用
accept
,并为每个新连接创建一个新线程:
for(;;)
{
int newsockfd = accept(sockfd, (struct sockaddr *)&host_addr, (socklen_t *)&host_addrlen);
if(newsockfd < 0)
{
sendf(stderr, LOG_ERROR, "Failed to accept connection...\n");
continue;
}
pthread_t thread;
if(pthread_create(&thread, NULL, handler, (void *)&newsockfd) != 0)
{
sendf(stderr, LOG_ERROR, "Failed to create a new thread...\n");
return -4;
}
}
我创建线程,同时将套接字文件描述符(表示客户端和服务器之间的新连接)发送到新线程。
处理新创建的线程的函数如下所示:
void * handler(void * argument)
{
int sockfd = *((int *)argument);
struct sockaddr_in client_addr;
int client_addrlen = sizeof(client_addr);
int sockn = getpeername(sockfd, (struct sockaddr *)&client_addr, (socklen_t *)&client_addrlen);
if(sockn < 0)
{
sendf(stderr, LOG_ERROR, "Failed to get client's address, got \x1b[35msockn\x1b[0m \x1b[33;3m%d\x1b[0m...\n", sockn);
pthread_exit(NULL);
}
char * input = malloc(sizeof(char) * BUFFER_SIZE);
int valread = read(sockfd, input, BUFFER_SIZE);
if(valread < 0)
{
sendf(stderr, LOG_ERROR, "Failed to read from socket, got \x1b[35mvalread\x1b[0m \x1b[33;3m%d\x1b[0m...\n", valread);
free(input);
pthread_exit(NULL);
}
char * method = malloc(sizeof(char) * BUFFER_SIZE);
char * url = malloc(sizeof(char) * BUFFER_SIZE);
char * version = malloc(sizeof(char) * BUFFER_SIZE);
sscanf(input, "%s %s %s", method, url, version);
sendf(stdout, LOG_DEBUG, "Client \x1b[33;3m%s:%u\x1b[0m has sent a \x1b[33;3m%s\x1b[0m request to \x1b[33;3m%s\x1b[0m!\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), method, url);
...
当连接损坏时,我得到:
[ERROR]: Failed to get client's address, got sockn -1...
使用一些调试工具,我检查并查看
method
,
url
和
verison
设置为
NULL
.功能
getpeername
也返回-1。
函数
sendf
只是类似printf的基本函数,但似乎不是问题的原因。
有人发现这里有什么问题吗?