某公司的一道试题
2008-05-20 03:30
260 查看
该代码实现了一个客户端回射程序,即从用户获得输入的一行文本,发给服务器,当接到服务器的应答信息后,打印该信息。请阅读代码回答问题。
#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模型好用些
#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模型好用些
相关文章推荐
- 某公司的一道机试题: 计算任一天是星期几
- 某知名IT公司最近的一道笔试编程题
- 公司笔试c、c++试题
- 【转】一道SQL SERVER DateTime的试题
- 小试身手__一道华为机试题
- 如何在VC++6.0中设置条件断点?--- 某公司实习生招聘面试试题
- 一道试题
- 一道试题引发的血案 int *ptr2=(int *)((int)a+1)
- 一道华为编程大赛的试题
- 一道简单的机试题,考倒多少人?
- 单链表的就地逆置 (单链表带头结点)(某公司校园招聘面试试题)
- 一道试题:找到拥有相同标签的用户对
- 一道SQL统计试题
- 一道百度试题
- [转] 某大型IT公司招网络工程师认证试题精选(要求:CCNA或 HCNE以上)
- 某公司招聘总经理的真实试题[转贴]
- 聊聊这个与代码优化有关的选择题 (某公司实习生招聘笔试试题)
- 试题:网易笔试的一道题目
- 【算法系列】一道笔试试题——回文数算法
- 某公司面试java试题之【一】,看看吧,说不定就是你将要做的题