C 在从套接字写入和读取时退出
C exits when writing and reading from sockets
我正在尝试用 C 编写一个非常基本的 http 服务器,但我看到的一些 C 行为让我感到困惑。据我所知,这段代码应该永远循环(当客户端是 netcat 时它会循环)但是当客户端是浏览器时,它就会退出(呈现“hello world”之后)。
如果它退出时出现错误,那么一切就都说得通了。但它似乎只是愉快地退出而没有任何错误信息!你不能 运行 远离这样的无限 while 循环!
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
#include<stdlib.h>
int main(int argc , char *argv[])
{
int socket_desc , new_socket , c;
struct sockaddr_in server , client;
char *message;
char *buffer = "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 12\n\nHello world!";
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("bind failed");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
int read_size;
char client_message[2000];
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
while( 1 )
{
write(new_socket , buffer , strlen(buffer));
while (1){
read_size = recv(new_socket , client_message , 2000 , 0);
//send the exact same message again
write(new_socket , buffer , strlen(buffer));
}
}
if (new_socket<0)
{
perror("accept failed");
return 1;
}
return 0;
}
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *)&c);
while (1)
{
write(new_socket, buffer, strlen(buffer));
while (1)
{
read_size = recv(new_socket, client_message, 2000, 0);
//send the exact same message again
write(new_socket, buffer, strlen(buffer));
}
}
您在您的程序中只调用了一次 accept
- 即您只会收到一个传入请求。并且您无限地将相同的缓冲区发送回新连接 - 这不是网络通信的工作方式。
您可能想要做的是循环调用 accept
并为每个连接提供缓冲区。
例如:
while (1)
{
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *)&c);
write(new_socket, buffer, strlen(buffer));
close(new_socket);
}
我正在尝试用 C 编写一个非常基本的 http 服务器,但我看到的一些 C 行为让我感到困惑。据我所知,这段代码应该永远循环(当客户端是 netcat 时它会循环)但是当客户端是浏览器时,它就会退出(呈现“hello world”之后)。
如果它退出时出现错误,那么一切就都说得通了。但它似乎只是愉快地退出而没有任何错误信息!你不能 运行 远离这样的无限 while 循环!
#include<stdio.h>
#include<string.h> //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h> //write
#include<stdlib.h>
int main(int argc , char *argv[])
{
int socket_desc , new_socket , c;
struct sockaddr_in server , client;
char *message;
char *buffer = "HTTP/1.1 200 OK\nContent-Type: text/plain\nContent-Length: 12\n\nHello world!";
//Create socket
socket_desc = socket(AF_INET , SOCK_STREAM , 0);
if (socket_desc == -1)
{
printf("Could not create socket");
}
//Prepare the sockaddr_in structure
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons( 8888 );
//Bind
if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
{
puts("bind failed");
return 1;
}
puts("bind done");
//Listen
listen(socket_desc , 3);
//Accept and incoming connection
puts("Waiting for incoming connections...");
c = sizeof(struct sockaddr_in);
int read_size;
char client_message[2000];
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
while( 1 )
{
write(new_socket , buffer , strlen(buffer));
while (1){
read_size = recv(new_socket , client_message , 2000 , 0);
//send the exact same message again
write(new_socket , buffer , strlen(buffer));
}
}
if (new_socket<0)
{
perror("accept failed");
return 1;
}
return 0;
}
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *)&c);
while (1)
{
write(new_socket, buffer, strlen(buffer));
while (1)
{
read_size = recv(new_socket, client_message, 2000, 0);
//send the exact same message again
write(new_socket, buffer, strlen(buffer));
}
}
您在您的程序中只调用了一次 accept
- 即您只会收到一个传入请求。并且您无限地将相同的缓冲区发送回新连接 - 这不是网络通信的工作方式。
您可能想要做的是循环调用 accept
并为每个连接提供缓冲区。
例如:
while (1)
{
new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t *)&c);
write(new_socket, buffer, strlen(buffer));
close(new_socket);
}