【问题标题】:Socket send() and recv() not working套接字 send() 和 recv() 不起作用
【发布时间】:2014-05-22 15:59:01
【问题描述】:

我写了一个简单的代码来send()recv()数据,但是当我recv() 数据。发送没有任何错误。

服务器代码:

struct sockaddr_in name;
char *buf;

int main(int agrc, char** argv) {

int sock, new_sd;   //sock is this socket, new_sd is connection socket
int adrlen, cnt;

name.sin_family=AF_INET;
name.sin_port=htons(6050);

sock = socket(AF_INET, SOCK_STREAM, 0);

if (sock < 0) {
    printf("\nserver socket failure ");
    printf("\nServer: ");
    exit(1);
}
printf("sockfd=%d\n",sock);
adrlen=(socklen_t)sizeof(name);
if((bind (sock,(struct sockaddr *)&name,adrlen)) < 0)
   printf("\nBind failure");
if(listen(sock, 5) < 0)
   printf("\nlisten error ");
printf("listen done\n");
while(1) {
    if( new_sd =(accept(sock,(struct sockaddr *)&name,(socklen_t*)&adrlen)) < 0) {
        printf("\nserver accept failure ");
        exit(1);
    }
    printf("new_sd=%d",new_sd);

    buf = (char *)malloc(14);
    if((recv(new_sd,(void *)buf,14,MSG_WAITALL)) < 0){
       printf("\nError receiving data ");
        exit(1);
    }
}   //end while
return 0;
}

客户端代码:

char buf[14];
struct sockaddr_in name;

int main(int agrc, char** argv) {

int sock, new_sd, adrlen, cnt;
name.sin_family=AF_INET;
name.sin_port=htons(6050);

sock = socket(AF_INET, SOCK_STREAM, 0);

if (sock < 0) {
   printf("\nserver socket failure ");
   printf("\nServer: ");
    exit(1);
}

//stuff for server socket
printf("sock is %d\n",sock);
adrlen=(socklen_t)sizeof(name);


if((connect(sock,(struct sockaddr *)&name,adrlen)) < 0) {
    printf("\nclient connection failure ");
    exit(1);
}

printf("\nSuccessful connection from client 1");

strcpy(buf,"\nclientsend");

if((send(sock,(void *)buf,strlen(buf), 0)) < 0) {
    printf("\nError sending data from client 1 ");
    exit(1);
}
printf("\nExiting normally");
return 0;
}

【问题讨论】:

  • 代码太多,错误的细节太少。至少打印出错误信息(使用perror),这样你就知道是什么导致recv失败了。
  • 您忘记在struct sockaddr_in 结构中添加要连接的地址。
  • 错误处理是……嗯……printf("oh no, fatal failure"); no problem, let's continue...

标签: c sockets


【解决方案1】:

可能会出现许多错误。您应该使用 GetLastError() 来了解更多信息。

另外,我注意到在客户端和服务器示例中,您都没有完全初始化“sockaddr_in name”,例如 name.ai_addr 保持原样。在 TCP (SOCK_STREAM) 的情况下,您需要一个地址来连接。

【讨论】:

  • 你的意思是WSAGetLastError().
【解决方案2】:

我认为这可能是您的问题:您仅从客户端发送 11 个字节,但服务器在等待 14 个字节时阻塞。客户端发送 11 个字节后退出,导致套接字层终止连接。然而,当启动关闭序列时,服务器仍在等待额外的 3 个字节。

为避免这种情况,您可以在客户端发送一个包含消息长度的固定大小的标头。在服务器端,首先recv header,提取消息的长度,然后用这个长度再次调用recv。

【讨论】:

  • recv() 在收到一个或多个字节后立即解除阻塞。它不会“阻止等待 [所有] 14 个字节”。
猜你喜欢
  • 1970-01-01
  • 2016-04-04
  • 2013-11-16
  • 1970-01-01
  • 2013-08-20
  • 2014-01-14
  • 1970-01-01
  • 2013-03-08
  • 1970-01-01
相关资源
最近更新 更多