我正在从http://www.linuxhowtos.org/C_C++/socket.htm处修改服务器代码。我想在客户端断开连接时重置服务器,以便下次为客户端准备就绪。但是,当我关闭客户端时,服务器关闭,服务器日志中未写入任何内容。由于我一次只想处理一个客户,因此我不需要分叉吗?否则,服务器可以正常工作,并响应我从我用C#编写的客户端发送的消息。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
FILE *fp;
double square(double x)
{
return x*x;
}
void error(const char *msg)
{
fprintf(fp, "%s", msg);
fprintf(fp, "%s", "\n");
}
int main(int argc, char *argv[])
{
fp = fopen("serverlog.txt", "a");
int sockfd;
int newsockfd;
int portno = 43635;
int clientIsConnected;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
while (1)
{
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
error("ERROR opening socket");
close(sockfd);
return 0;
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
{
error("ERROR on binding");
close(sockfd);
return 0;
}
if (listen(sockfd,5) < 0)
{
error("ERROR on listen");
close(sockfd);
return 0;
}
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
{
error("ERROR on accept");
close(newsockfd);
close(sockfd);
return 0;
}
clientIsConnected = 1;
while (clientIsConnected)
{
bzero(buffer, 256);
n = read(newsockfd, buffer, 255);
if (n < 0)
{
error("ERROR reading from socket");
clientIsConnected = 0;
break;
}
double x = atof(buffer);
double squared = square(x);
char response[256];
sprintf(response, "%f", squared);
n = write(newsockfd, response, strlen(response));
if (n < 0)
{
error("ERROR writing to socket");
clientIsConnected = 0;
break;
}
}
}
close(sockfd);
return 0;
}
答案 0 :(得分:1)
您的服务器可能由于收到SIGPIPE而停止。您可以使用
signal(SIGPIPE,SIG_IGN);
保持程序运行,您可以在应用程序代码中处理封闭的通信。