在@Medinoc、@someuser 和@Elchonon 的建议之后,我通过以下方式更正了我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <signal.h>
#define SERVER_PORT 80
int nStatus, nMainSocketId;
void onInt () {
printf("You have pressed CTRL-C.\n");
nStatus = 0;
shutdown(nMainSocketId, 2);
}
void onQuit () {
printf("You have pressed CTRL-\\.\n");
nStatus = 0;
shutdown(nMainSocketId, 2);
}
int main () {
int nReqSocketId, nReqSize = 1024;
nMainSocketId = socket(AF_INET, SOCK_STREAM, 0);
char *sRequest = malloc(nReqSize);
socklen_t nAddrLen;
struct sockaddr_in oAddress;
signal(SIGINT, onInt);
signal(SIGQUIT, onQuit);
oAddress.sin_family = AF_INET;
oAddress.sin_addr.s_addr = INADDR_ANY;
oAddress.sin_port = htons(SERVER_PORT);
nStatus = 1;
printf("\n W E L C O M E!\n\nPress CTRL-C or CTRL-\\ to quit.\n");
if (nMainSocketId == 0) {
fprintf(stderr, "Error during the creation of the socket\n");
return 1;
}
if (bind(nMainSocketId, (struct sockaddr *) &oAddress, sizeof(oAddress))) {
fprintf(stderr, "The port %d is busy\n", SERVER_PORT);
close(nMainSocketId);
return 1;
}
printf("HTTP server listening on port %d\n", SERVER_PORT);
while (nStatus) {
if (listen(nMainSocketId, 10) < 0) {
perror("server: listen");
close(nMainSocketId);
return 1;
}
nReqSocketId = accept(nMainSocketId, (struct sockaddr *) &oAddress, &nAddrLen);
if (nReqSocketId < 0) {
perror("server: accept");
close(nMainSocketId);
return 1;
}
recv(nReqSocketId, sRequest, nReqSize, 0);
if (nReqSocketId > 0){
printf("The Client is connected...\n\n%s\n", sRequest);
}
write(nReqSocketId, "HTTP/1.1 200 OK\n", 16);
write(nReqSocketId, "Content-length: 50\n", 19);
write(nReqSocketId, "Content-Type: text/html\n\n", 25);
write(nReqSocketId, "<html><body><h1>Hello world!!!</h1></body></html>\n", 50);
close(nReqSocketId);
}
printf("Goodbye!\n");
close(nMainSocketId);
return 0;
}
进程软终止,现在!!但是,不幸的是,套接字没有!:( ...所以每当我按下 CTRL-C 或 CTRL-\ 以退出时,我都会收到以下消息:
server: accept: Invalid argument
有什么建议可以解决吗?
编辑
@alk
谢谢您的回答!您建议我使用另一种方法来软终止我的网络服务器...:
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <signal.h>
#define SERVER_PORT 80
int bExiting, nMainSocketId;
void terminateServer () {
if (bExiting) { return; }
printf("\n\nTerminating server...\n");
close(nMainSocketId);
bExiting = 1;
}
int main () {
int nRecvResult = -1, nReqSocketId = -1;
size_t nReqSize = 1024;
char * sRequest = malloc(nReqSize);
socklen_t nAddrLen;
struct sockaddr_in oAddress = {0};
printf("\n W E L C O M E!\n\nPress CTRL-C or CTRL-\\ to quit.\n");
signal(SIGINT, terminateServer);
signal(SIGQUIT, terminateServer);
oAddress.sin_family = AF_INET;
oAddress.sin_addr.s_addr = INADDR_ANY;
oAddress.sin_port = htons(SERVER_PORT);
nMainSocketId = socket(AF_INET, SOCK_STREAM, 0);
if (nMainSocketId < 0) {
perror("server: socket() failed");
return 1;
}
if (bind(nMainSocketId, (struct sockaddr *) &oAddress, sizeof(oAddress))) {
perror("server: bind() failed");
terminateServer();
return 1;
}
printf("HTTP server listening on port %d\n", SERVER_PORT);
while (bExiting == 0) {
if (listen(nMainSocketId, 10) < 0) {
perror("server: listen() failed");
terminateServer();
return 1;
}
nReqSocketId = accept(nMainSocketId, (struct sockaddr *) &oAddress, &nAddrLen);
if (bExiting) { break; }
if (nReqSocketId < 0) {
perror("server: accept failed()");
terminateServer();
return 1;
}
nRecvResult = recv(nReqSocketId, sRequest, nReqSize, 0);
if (nRecvResult < 0) {
perror("server: recv() failed");
terminateServer();
return 1;
}
if (nRecvResult == 0) {
printf("The client is disconnected. Waiting for another connection...\n");
close(nReqSocketId);
continue;
}
printf("The client is connected...\n\n%s\n", sRequest);
/* This is only a simple "Hello world"... */
write(nReqSocketId, "HTTP/1.1 200 OK\n", 16);
write(nReqSocketId, "Content-length: 50\n", 19);
write(nReqSocketId, "Content-Type: text/html\n\n", 25);
write(nReqSocketId, "<html><body><h1>Hello world!!!</h1></body></html>\n", 50);
close(nReqSocketId);
}
free(sRequest);
printf("Goodbye!\n");
return 0;
}
你怎么看待这件事?我应该添加一些东西吗?
不过,我还有另一个问题。我可以将 fprintf() 与文件描述符结合使用来替代 write() 吗?如何?