客户端与服务器能连接 ,但是服务器返回的信息客户端收不到

xiaoxinjinli 2008-09-21 10:41:57
下面代码是从UNIX转过来的,这是一个C\S模式的。客户端的CONNECT能连上服务器,但是下面的一条语句n=recv(sock, buf,sizeof(buf),0);好像根本没执行(是不是阻塞了?)
而客户端一旦连接后会执行send(clientfd,buf,strlen(buf),0);语句的,把BUF的内容传给响应套接字(是发送失败??)

最后一个疑问:服务器接受客户端而产生一个响应套接字clientfd(服务器上的套接字),通过send语句把BUF发送到clientfd就相当于发送到了客户端上的套接字了吗??还是在BUF发送到clientfd后,还需要执行一些语句使clientfd发送到客户端的套接字。

请帮忙解答,在这里先谢谢了!!!!!!!


代码:
/*
-------------------------------------------------------------------------------
程序:client.c
目的:创建一个套接字,通过网络连接一个服务器,并打印来自服务器的信息
语法:client[host[port]]
host -运行服务器计算机的名字
port -服务器兼听套接字所用协议端口
注意:两个参数都是可选的。如果未指定主机名,客户使用localhost;如果未指定端口号,
客户机将使用PROTOPORT中给定的缺省的协议端口号
--------------------------------------------------------------------------------
*/


#include<stdafx.h>
#include<winsock2.h>
#include<stdio.h>
#include<stdlib.h>
#pragma comment(lib,"ws2_32.lib")



#define PROTOPORT 5188
//#define errno WSAGetLastError()
char *localhost="localhost";


void main(int argc,char **argv)
{

WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 1,1 );
int err = WSAStartup( wVersionRequested, &wsaData );
if(err!=0){return;}
if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1){

WSACleanup();
return ;
}

struct hostent *ptrh;
struct sockaddr_in servaddr;
SOCKET sock;
int port;
char *host;
int n;
char buf[1000];


//printf("%s\n",argv[0]);
//printf("%d",argc);

memset((char *)& servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;


if(argc>2){

port = atoi(argv[2]);
// port = *argv[2];
}
else{

port = PROTOPORT;
}
//printf("%d",port);

if(port>0)

servaddr.sin_port = htons((unsigned short)port);
else{

fprintf(stderr,"bad port number%S\n",argv[2]);
exit(1);
}


if(argc>1){

host = argv[1];
}else{

host = localhost;
}


ptrh = gethostbyname(host);
if((char *)ptrh == NULL){

fprintf(stderr,"invalid host:%s\n",host);
exit(1);
}


memcpy(&servaddr.sin_addr,ptrh->h_addr,ptrh->h_length);


sock =socket(AF_INET,SOCK_STREAM,0);
if(sock==INVALID_SOCKET){

fprintf(stderr,"socket creation failed\n");
exit(1);
}


if(connect(sock,(struct sockaddr *)&servaddr,sizeof(servaddr)) == INVALID_SOCKET){

fprintf(stderr,"connet failed\n");
exit(1);
}

n=recv(sock, buf,sizeof(buf),0);

while (n>0){

printf("dfsdfsdhfjksdfks");
n=recv(sock,buf,sizeof(buf),0);
}


closesocket(sock);

exit(0);


}




-------------------------------------------
*程序:server.c
*目的:分配一个套接字,然后反复执行如下几步。
*(1)等待客户的下一个连接
*(2)发送一个短消息给客户
*(3)关闭与客户的连接
*(4)转向第1步
*命令行语法server[port]
-------------------------------------------------

#include<stdafx.h>
#include<winsock2.h>
#include<stdio.h>
#include<stdlib.h>
#pragma comment(lib,"ws2_32.lib")


#define PROTOPORT 5188
//#define errno WSAGetLastError()
#define QLEN 6
int visits = 0;
char *localhost="localhost";


void main(int argc,char **argv)
{

WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 1,1 );
int err = WSAStartup( wVersionRequested,

&wsaData );
if(err!=0){return;}
if(LOBYTE(wsaData.wVersion)!=1||HIBYTE

(wsaData.wVersion)!=1){

WSACleanup();
return ;
}


// struct hostlent *ptrh;
struct sockaddr_in servaddr;
struct sockaddr_in clientaddr;
SOCKET listenfd,clientfd;
int port;
int alen;
char buf[1000];



memset((char *)&servaddr,0,sizeof(struct sockaddr_in));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;


if(argc>1){

port = atoi(argv[1]);
}else{

port = PROTOPORT;
}
if(port>0){

servaddr.sin_port = htons((u_short)port);
}else{

fprintf(stderr,"bad port number%S\n",argv[1]);
exit(1);
}

listenfd = socket(AF_INET,SOCK_STREAM,0);
if(listenfd == INVALID_SOCKET){

fprintf(stderr,"socket creation failed\n");
exit(1);
}



if (bind(listenfd ,(struct sockaddr*)&servaddr,sizeof

(servaddr))<0){

fprintf(stderr,"bind failed\n");
exit(1);
}


if (listen(listenfd,QLEN)<0){

fprintf(stderr,"listen failed\n");
exit(1);
}



while(1){
alen = sizeof(clientaddr);
if(clientfd = accept(listenfd,(struct

sockaddr*)&clientaddr ,&alen)<0){

fprintf(stderr,"accept failed\n");
exit(1);
}

visits++;
printf("访问是第%d\n",visits);

sprintf(buf,"this server has been %D

times\n",visits);
send(clientfd,buf,strlen(buf),0);
closesocket(clientfd);
}


}
...全文
256 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
cnzdgs 2008-09-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 tabby 的回复:]
引用 2 楼 cnzdgs 的回复:
默认情况下socket是阻塞模式,recv在没有数据的时候会阻塞,阻塞并不会导致错误,所以你这样写没有问题。问题出在server上:
=的优先级低于 <,这样改一下:
if ((clientfd = accept(listenfd,(struct sockaddr*)&clientaddr ,&alen)) < 0)

接收返回的clientfd就是与client连接的socket,用这个socket向对方发送数据和从对方接收数据。


呵呵,这也看出来了,真细心.. 直接运行测试了?
[/Quote]
没运行,用眼睛逐行扫描了一下,呵呵。
xiaoxinjinli 2008-09-22
  • 打赏
  • 举报
回复
谢谢各位,特别感谢2楼的大哥,自己不小心啊,浪费大家时间了 谢谢!!!!!
Wenxy1 2008-09-22
  • 打赏
  • 举报
回复
1, socket默认是阻塞的。
2, 发送失败,输出一下错误码,检查是什么错误,根据MSDN来处理。
3, 通过send语句把BUF发送到clientfd就相当于发送到了客户端上的套接字了吗??send的返回值是已发送的字节数。
xsc2001 2008-09-21
  • 打赏
  • 举报
回复
我觉得出在你的下面这段代码上:
if(connect(sock,(struct sockaddr *)&servaddr,sizeof(servaddr)) == INVALID_SOCKET){

fprintf(stderr,"connet failed\n");
exit(1);
}

n=recv(sock, buf,sizeof(buf),0);

while (n>0){

printf("dfsdfsdhfjksdfks");
n=recv(sock,buf,sizeof(buf),0);
}
你不应该在连接完后马上就接收数据,不应该马上调用recv函数接收数据,而是先判断一下是否有数据来,有数据来则开始接收。
最好是用select和FD_ISSET(sock, &set)判断一下有数据了才开始接收。因为你刚连接成功后就去数据,而你的服务器还没有开始发数据呢,这样你revc的时候返回的n<=0所以程序直接往下执行并关闭了Socket。
所以是你可以在连接成功后在,接收数据之间加一个Sleep(1000);这样试一下,这样也会好使,但是并不能保证任何情况下都好用,最好是用select和FD_ISSET进行判断。
内存泄漏 2008-09-21
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 cnzdgs 的回复:]
默认情况下socket是阻塞模式,recv在没有数据的时候会阻塞,阻塞并不会导致错误,所以你这样写没有问题。问题出在server上:
=的优先级低于 <,这样改一下:
if ((clientfd = accept(listenfd,(struct sockaddr*)&clientaddr ,&alen)) < 0)

接收返回的clientfd就是与client连接的socket,用这个socket向对方发送数据和从对方接收数据。
[/Quote]

呵呵,这也看出来了,真细心.. 直接运行测试了?
cnzdgs 2008-09-21
  • 打赏
  • 举报
回复
默认情况下socket是阻塞模式,recv在没有数据的时候会阻塞,阻塞并不会导致错误,所以你这样写没有问题。问题出在server上:
=的优先级低于<,这样改一下:
if ((clientfd = accept(listenfd,(struct sockaddr*)&clientaddr ,&alen)) < 0)

接收返回的clientfd就是与client连接的socket,用这个socket向对方发送数据和从对方接收数据。
aj3423 2008-09-21
  • 打赏
  • 举报
回复
网络程序 sockmon抓包分析

18,363

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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