server.c:从客户端读字符,然后将每个字符转换为大写并回送给客户端。

client.c:从命令行参数中获得一个字符串发给服务器,然后接收服务器返回的字符串并打印。
others...
1.该例子不仅功能简单,而且简单到几乎没有什么错误处理,我们知道,系统调用不能保证每次都成功,必须进行出错处理,这样一方面可以保证程序逻辑正常,另一方面可以迅速得到故障信息。
为使错误处理的代码不影响主程序的可读性,需要把与socket相关的一些系统函数加上错误处理代码包装成新的函数,做成一个模块!
2.目前实现的client每次运行只能从命令行读取一个字符串发给服务器,再从服务器收回来,现在我们把它改成交互式的,不断从终端接受用户输入并和server交互。
3.使用fork并发处理多个client的请求! 网络服务器通常用fork来同时服务多个客户端,父进程专门负责监听端口,每次accept一个新的客户端连接就fork出一个子进程专门服务这个客户端。但是子进程退出时会产生僵尸进程,父进程要注意处理sigchld信号和调用wait清理僵尸进程。
4.setsockopt
表示允许创建端口号相同但ip地址不同的多个socket描述符。在server代码的socket()和bind()调用之间插入如下代码:
int opt = 1;
setsockopt(listenfd, sol_socket, so_reuseaddr, &opt, sizeof(opt));
原因:client终止时自动关闭socket描述符,server的tcp连接收到client发的fin段后处于time_wait状态。tcp协议规定,主动关闭连接的一方要处于time_wait状态,等待两个msl(maximum segment lifetime)的时间后才能回到closed状态,因为我们先ctrl-c终止了server,所以server是主动关闭连接的一方,在time_wait期间仍然不能再次监听同样的server端口。msl在rfc1122中规定为两分钟,但是各操作系统的实现不同,在linux上一般经过半分钟后就可以再次启动server了。
5.使用select
select是网络程序中很常用的一个系统调用,它可以同时监听多个阻塞的文件描述符(例如多个网络连接),哪个有数据到达就处理哪个,这样,不需要fork和多进程就可以实现并发服务的server。
<a target="_blank" href="http://www.akaedu.org/down/linuxc.pdf"></a>
<a target="_blank" href="http://www.akaedu.org/down/linuxc.pdf">原文地址</a>