求大侠帮忙分析一个简单的socket程序。。

ajige 2010-10-18 11:44:49
欲实现的功能如下:client从stdin读入一个shell命令(如date,ls这种有输出结果的命令),向server发送该命令,然后server执行命令后,将执行的结果返回给client,client再返回的结果打印出来。
源码如下:

// server 端
#include "unp.h"
#include <time.h>
#include <stdio.h>
int
main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[MAXLINE], line[MAXLINE];
time_t ticks;
int n=0, resue=1;
char end[4]="end";
char *ppp;
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
setsockopt (listenfd,SOL_SOCKET,SO_REUSEADDR,&resue,sizeof(int));
FILE* fpin;
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(13); /* daytime server */
Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
Listen(listenfd, LISTENQ);
connfd = Accept(listenfd, (SA *) NULL, NULL);

while ((n =recv(connfd,buff,40,0))>0){
printf("%d\n",n);
fflush(stdout);
buff[n]=0;// 很重要!!
if ((fpin = popen (buff,"r"))==NULL)
err_sys("popen error");
bzero(line,MAXLINE);
for (;;){
ppp= fgets(line,MAXLINE,fpin);
send(connfd,line,strlen(line),0);
if(ppp==NULL) // end作为传输的结束符。
{
ppp = "end";
send(connfd,ppp,strlen(ppp),0)
break;
}

}
if (pclose(fpin)==-1)
err_sys("pclose error");
// memset(buff,40,0);
}
Close(connfd);
exit(0);
}

// client 端
#include "unp.h"
int
main(int argc, char **argv)
{
int sockfd, n;
char recvline[100];
struct sockaddr_in servaddr;
char cmdstring[40];
if (argc != 2)
err_quit("usage: a.out <IPaddress>");
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13); /* daytime server */
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
err_quit("inet_pton error for %s", argv[1]);
if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");

while (fgets(cmdstring,40,stdin)!=NULL) {
if( write(STDOUT_FILENO,cmdstring,strlen(cmdstring))<0)
err_sys("write to stdout error");
send (sockfd, cmdstring, strlen(cmdstring),0);

for (;;) {
if ((n = recv(sockfd,recvline,MAXLINE,0))>0) {
recvline[n]=0; // 很重要
fputs(recvline,stdout);
if (!strncasecmp(recvline,"end",3)) // 判断数据是否接收完毕
break;
}
}
exit(0);
}
}




现在的情况是:client可以向server发送一次命令,并且命令的结果可以返回并显示。
问题是: client端接收一次数据后,第二次再调用 recv函数时,会一直block.
请教 一下,这是为什么呢?
...全文
65 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
justkk 2010-10-18
  • 打赏
  • 举报
回复
if ((n = recv(sockfd,recvline,MAXLINE,0))>=0)
justkk 2010-10-18
  • 打赏
  • 举报
回复
那就是服务器应答的数据中没有包含"end"..
你只判断了recv返回>0的情况,没有检查==0的情形(表示连接被关闭)
不要用这种方式检测,你可以判断连接是否关闭
for (;;) {
if ((n = recv(sockfd,recvline,MAXLINE,0))>=0) {
recvline[n]=0; // 很重要
fputs(recvline,stdout);
}
justkk 2010-10-18
  • 打赏
  • 举报
回复
执行顺序有问题吧,服务器不是core掉了吧
ppp= fgets(line,MAXLINE,fpin);
send(connfd,line,strlen(line),0);
if(ppp==NULL) // end作为传输的结束符。

应该把if(ppp==NULL)这一段放在send(connfd,line,strlen(line),0);之前。。
justkk 2010-10-18
  • 打赏
  • 举报
回复
你单步跟踪的时候,ppp是否为NULL呢?
其实用这种方式表示结束,也是有局限性的
ajige 2010-10-18
  • 打赏
  • 举报
回复

for (;;){
ppp= fgets(line,MAXLINE,fpin);
send(connfd,line,strlen(line),0);
if(ppp==NULL) // end作为传输的结束符。
{
ppp = "end";
send(connfd,ppp,strlen(ppp),0) // send end
break;
}

}

这段代码,我在单步调试时,发现send end 对应的语句没有被执行,即程序跳过了该行.这是为什么呢??

23,116

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧