一些注释没有特定的顺序:
- 您浪费了太多机会去了解确切的错误:
if(listen(sockfd,BACKLOG) == -1)
{
printf(“ERROR: Failed to listen Port %d.n”, PORT);
return (0);
}
此块绝对应包含a
perror("listen")或类似名称。当错误详细信息将通过进行报告时,始终包含perror()或包含
strerror()在每个错误处理块中
errno。具有确切的故障原因将为您节省编程时间,并且在事情将来无法按预期运行时为您和您的用户节省时间。
- 您的错误处理需要进一步标准化:
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
{
printf(“ERROR: Failed to obtain Socket Descriptor.n”);
return (0);
}
这应该 不是
return 0,因为这将标志着该外壳的程序运行完成没有错误。您应该
return1(或使用
EXIT_SUCCESS和
EXIT_FAILURE)发出异常退出信号。
else printf("[Server] Server has got connected from %s.n", inet_ntoa(addr_remote.sin_addr)); 在前面的代码块中,您遇到了错误情况,但仍然继续执行。这是获得非常不良行为的快速方法。这应该重新启动主服务器循环或退出子进程或类似的过程。(取决于您是否保留多进程服务器。)
if(!fork()){前面的代码块忘记了
fork()失败的原因 。
fork()会并且确实会失败-尤其是在大学中常见的共享托管环境中-
因此您应该为来自失败,孩子,父母的完整而复杂的 三个 可能的返回值做好准备
fork()。
看来您正在
fork()
不加选择地使用;您的客户端和服务器都非常简单,它们的运行方式意味着 不能 同时为多个客户端提供服务。您可能应该严格遵循每个流程,至少要等到算法完全调试好并找出某种方式同时运行多个客户端为止。我希望这是您现在遇到的问题的根源。您需要使用函数来封装细节。编写一个函数以连接到服务器,编写一个函数以发送文件,编写一个函数以写入文件,等等。编写一个函数以处理复杂的部分写入。(我特别建议
writen
从Unix环境书的源代码中的 “ 高级编程”中窃取该功能。文件lib/writen.c
。)如果正确编写了这些功能,则可以在客户端和服务器中重新使用它们。(有点像将它们放入utils.c
并像那样编译程序gcc -o server server.c utils.c
。)
具有较小的功能,每个功能都可以做一件事情,这样您就可以一次专注于少量的代码, 并 为每个功能编写很少的测试,这将帮助您缩小仍需要改进的代码部分的范围。



