1 回答

TA贡献1846条经验 获得超7个赞
关于服务器与客户端的通信,有几个小问题,比如不正确的变量类型和缺乏错误检查。
我在我的评论前面加上了>>'条件编译'来展示我如何用建议的改进替换了 OPs 代码的某些部分。
警告:由于服务器不知道从客户端接收的预期字节数,因此答案不包括循环,试图检索客户端预期的所有字节
char buf[ RECV_BUF_SIZE +1 ]; // >> +1 for string terminator
while (1)
{
// >> the third parameter is a 'socklen_t', not an 'int'
socklen_t addrlen = sizeof(cli_addr);
int clientfd =
accept(socketfd, (struct sockaddr*) &cli_addr, &addrlen);
if (clientfd < 0)
{
perror("accept error");
}
else
{
// >>recv() returns a `ssize_t`, not an `int`
ssize_t n_recv = recv(clientfd, buf, RECV_BUF_SIZE, 0);
#if 0
// >>this takes WAY too long, so the connection
// >>could timeout
// print everything, character by character.
char* tmp_buf = buf;
while (n_recv--) printf("%c", *tmp_buf++);
#else
if( n_recv < 0 )
{ // then an error occurred
perror( "recv failed" );
write( clientfd,
"receive error",
sizeof( "receive error" ) );
close( clientfd );
}
else if( n_recv == 0 )
{ // then client closed connection
printf( "%s\n",
"client closed connection" );
close( clientfd );
}
else
{ // some data received from client
buf[ n_recv ] = '\0'; // terminate string
printf( "%s\n", buf );
}
#endif
printf("\n\n****************************\n\n");
#if 0
FILE* res = fdopen(clientfd, "w");
fprintf(res, "HTTP/1.1 200 OK\r\n\r\n");
fclose(res);
shutdown(clientfd, SHUT_RDWR);
close(clientfd);
#else
ssize_t writeBytes;
if( (writeBytes =
write( clientfd,
"HTTP/1.1 200 OK\r\n\r\n",
strlen( "HTTP/1.1 200 OK\r\n\r\n" ) ) )
!= strlen( "HTTP/1.1 200 OK\r\n\r\n" ) )
{ // then incomplete write
printf( "%s\n",
"write didn't write all bytes to client" );
}
close( clientfd );
#endif
}
}
分享
编辑
跟随关于服务器与客户端的通信,有几个小问题,比如不正确的变量类型和缺乏错误检查。
我在我的评论前面加上了>>'条件编译'来展示我如何用建议的改进替换了 OPs 代码的某些部分。
警告:由于服务器不知道从客户端接收的预期字节数,因此答案不包括循环,试图检索客户端预期的所有字节
char buf[ RECV_BUF_SIZE +1 ]; // >> +1 for string terminator
while (1)
{
// >> the third parameter is a 'socklen_t', not an 'int'
socklen_t addrlen = sizeof(cli_addr);
int clientfd =
accept(socketfd, (struct sockaddr*) &cli_addr, &addrlen);
if (clientfd < 0)
{
perror("accept error");
}
else
{
// >>recv() returns a `ssize_t`, not an `int`
ssize_t n_recv = recv(clientfd, buf, RECV_BUF_SIZE, 0);
#if 0
// >>this takes WAY too long, so the connection
// >>could timeout
// print everything, character by character.
char* tmp_buf = buf;
while (n_recv--) printf("%c", *tmp_buf++);
#else
if( n_recv < 0 )
{ // then an error occurred
perror( "recv failed" );
write( clientfd,
"receive error",
sizeof( "receive error" ) );
close( clientfd );
}
else if( n_recv == 0 )
{ // then client closed connection
printf( "%s\n",
"client closed connection" );
close( clientfd );
}
else
{ // some data received from client
buf[ n_recv ] = '\0'; // terminate string
printf( "%s\n", buf );
}
#endif
printf("\n\n****************************\n\n");
#if 0
FILE* res = fdopen(clientfd, "w");
fprintf(res, "HTTP/1.1 200 OK\r\n\r\n");
fclose(res);
shutdown(clientfd, SHUT_RDWR);
close(clientfd);
#else
ssize_t writeBytes;
if( (writeBytes =
write( clientfd,
"HTTP/1.1 200 OK\r\n\r\n",
strlen( "HTTP/1.1 200 OK\r\n\r\n" ) ) )
!= strlen( "HTTP/1.1 200 OK\r\n\r\n" ) )
{ // then incomplete write
printf( "%s\n",
"write didn't write all bytes to client" );
}
close( clientfd );
#endif
}
}
添加回答
举报