下面代码是从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);
}
}

解决方案 »

  1.   

    默认情况下socket是阻塞模式,recv在没有数据的时候会阻塞,阻塞并不会导致错误,所以你这样写没有问题。问题出在server上:
    =的优先级低于<,这样改一下:
    if ((clientfd = accept(listenfd,(struct sockaddr*)&clientaddr ,&alen)) < 0)接收返回的clientfd就是与client连接的socket,用这个socket向对方发送数据和从对方接收数据。
      

  2.   

    我觉得出在你的下面这段代码上:
    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进行判断。
      

  3.   

    1, socket默认是阻塞的。
    2, 发送失败,输出一下错误码,检查是什么错误,根据MSDN来处理。
    3, 通过send语句把BUF发送到clientfd就相当于发送到了客户端上的套接字了吗??send的返回值是已发送的字节数。