该代码实现了一个客户端回射程序,即从用户获得输入的一行文本,发给服务器,当接到服务器的应答信息后,打印该信息。请阅读代码回答问题。
#include "unp.h" // 可认为这行是正确的,包含了所有以下函数用到的头文件。
Int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
if (argc != 2)
err_quit("usage: tcpcli ");
sockfd = socket(af_inet, sock_stream, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = af_inet;
servaddr.sin_port = htons(serv_port);
inet_pton(af_inet, argv[1], &servaddr.sin_addr);
connect(sockfd, (sa *) &servaddr, sizeof(servaddr));
str_cli(stdin, sockfd);
exit(0);
}
Void str_cli(file *fp, int sockfd)
{
int maxfdp1;
fd_set rset;
char sendline[maxline], recvline[maxline];
fd_zero(&rset);
for ( ; ; ) {
fd_set(fileno(fp), &rset);
fd_set(sockfd, &rset);
maxfdp1 = max(fileno(fp), sockfd);
select(maxfdp1, &rset, null, null, null);
if (fd_isset(sockfd, &rset)) {
if (readline(sockfd, recvline, maxline) == 0)
err_quit("str_cli: server terminated prematurely");
fputs(recvline, stdout);
}
if (fd_isset(fileno(fp), &rset)) {
if (fgets(sendline, maxline, fp) == null)
return;
writen(sockfd, sendline, strlen(sendline));
}
}
}
1、请指出程序编码不当的地方。
2、该代码是否能完整实现功能,如果不能,什么情况下会出现问题?
这题完全是《unix网络编程》中的例子,书上有详解
1. 不当的地方可能是主函数中socket函数未作错误处理
2. if (fgets(sendline, maxline, fp) == null)
return;
这里在批量输入时有问题,fgets判断返回stdio缓冲区的第一行,其余留在缓冲区中,然后就writen(sockfd, sendline, strlen(sendline);然后继续select,不管stdio缓冲区中还有待发送的数据。
另外,如果读到EOF,就return到主函数,然后退出了,但是可能还有数据在网络上,造成数据没有接收完全。
正确的方式,应该是:
void str_cli(file *fp, int sockfd)
{
int maxfdp1, stdineof, n;
fd_set rset;
char buf[maxline];
stdineof = 0;
fd_zero(&rset);
for ( ; ; ) {
if( stdineof == 0) {
fd_set(fileno(fp), &rset);
}
fd_set(sockfd, &rset);
maxfdp1 = max(fileno(fp), sockfd);
select(maxfdp1, &rset, null, null, null);
if (fd_isset(sockfd, &rset)) {
if((n = Read(sockfd, recvline, maxline)) == 0) {
if(stdineof == 1)
return;
else
err_quit("str_cli: server terminated prematurely");
write(fileno(stdout), buf, n);
}
if (fd_isset(fileno(fp), &rset)) {
if( (n=read(fileno(fp), buf, maxline)) == 0) {
stdineof = 1;
shutdown(sockfd, SHUT_WR);
FD_CLR(fileno(fp), &ret);
continue;
}
writen(sockfd, buf, n);
}
}
}
《unix网络编程》我是陆陆续续看的,始终没看完,觉得在linux上开发网络程序终是麻烦,《windows网络编程技术》倒是本好书,还是微软封装的那些IO模型好用些