我有一个在c代码中实现http服务器的任务。 它应该包括处理几个连接,但是现在我只想确保它只使用一个连接。 首先,这是我的代码:
return
这是我的问题: 为了测试我的代码,我在另一个linux终端中运行了以下命令:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#define BUF_SIZE 1025
int main(int argc, char **argv)
{
uint16_t portNum = 80;
int connfd = 0, listenFd;
struct sockaddr_in serv_addr, peer_addr;
if ((listenFd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("socket syscall failed: %s.\nExiting...\n", strerror(errno));
exit(EXIT_FAILURE);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(portNum);
if (bind(listenFd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)))
{
printf("bind syscall failed: %s\nExiting...\n", strerror(errno));
exit(EXIT_FAILURE);
}
if (listen(listenFd, 5))
{
printf("listen syscall failed: %s\nExiting...\n", strerror(errno));
exit(EXIT_FAILURE);
}
while (1)
{
/* new connection */
socklen_t addrsize = sizeof(struct sockaddr_in);
connfd = accept(listenFd, (struct sockaddr *) &peer_addr, &addrsize);
if (connfd < 0)
{
printf("\n Error : Accept Failed. %s \n", strerror(errno));
return 1;
}
char httpRequest[BUF_SIZE] = {0};
if ((recv(connfd, httpRequest, BUF_SIZE, 0)) == -1)
{
printf("recv syscall failed: %s\nExiting...\n", strerror(errno));
exit(EXIT_FAILURE);
}
char msg[BUF_SIZE] = {0};
strcpy(msg, "200 OK THIS IS A TEST");
printf("sending message...\n");
int len = strlen(msg);
if (send(connfd, msg, len, 0) < 0)
{
printf("SEND ERROR\n");
exit(EXIT_FAILURE);
}
printf("message sent!\n");
close(connfd);
close(listenFd);
// THIS IS FOR DEBUG - ignore...
return 0;
}
return EXIT_SUCCESS;
}
(其中ex.txt只是一个测试文件...) 这是问题: 我在服务器和curl输出中都看到了http请求,但似乎服务器的“发送”命令不起作用 - 在http rquest下面的curl窗口中它说:
curl -v loaclhost:80/~/ex.txt
任何想法?
答案 0 :(得分:1)
1024的缓冲区对于任何严重的问题都太小了。只是在本地玩,它会工作正常。如果您想要做一些严肃的工作,8192字节的缓冲区即使对于重负载也能正常工作。
recv()在大多数实现中都是阻塞函数,这意味着它将阻塞,直到它收到输入的字节数或客户端在发送数据后关闭连接。我没有看到你的套接字被定义并被视为非阻塞。所以这部分需要克服才能克服。
您的HTTP响应错误。
标题应如下所示:
"HTTP/1.1 200 OK\r\nStatus: 200 OK\r\nContent-Type: text/plain\r\n\r\n"
您还可以添加标题:
"Content-Length: 0"
因为除了标题之外你没有发回任何数据。
此外,如果您继续使用HTTP / 0.9或切换到HtTP / 1.0,您应该在向他发送数据后关闭与客户端的连接。
HTTP / 1.1支持打开的连接,但通常通过Keep-Alive和Connection标头进行控制。
答案 1 :(得分:-2)
好的,-1对我来说,由于strcpy中缺少'\ n'字符,它无效。