在TCP客户端/服务器程序中未收到消息

在TCP客户端/服务器程序中未收到消息

问题描述:

我试图实现一个tcp客户端和tcp服务器。我能够建立连接,但是当我从客户端发送消息时,服务器没有收到它,是的,我查看了以前的帖子,并且发现了很多类似的问题。我确实按照他们,但我仍然得到同样的错误。我得到的错误是从服务器端:在TCP客户端/服务器程序中未收到消息

recv: Socket operation on non-socket 

这是我的代码。如果你可以让我知道我做错了什么,我会很感激。我认为我的服务器实现存在问题。

服务器:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#define PORT 3490 
#define BACKLOG 10 

int main() 
{ 
    struct sockaddr_in server; 
    struct sockaddr_in dest; 
    int status,socket_fd, client_fd,num; 
    socklen_t size; 

    char buffer[10240]; 
    memset(buffer,0,sizeof(buffer)); 
    int yes = 1; 

    if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) { 
     fprintf(stderr, "Socket failure!!\n"); 
     exit(1); 
    } 

    if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { 
     perror("setsockopt"); 
     exit(1); 
    } 

    memset(&server, 0, sizeof(server)); 
    memset(&dest,0,sizeof(dest)); 
    server.sin_family = AF_INET; 
    server.sin_port = htons(PORT); 
    server.sin_addr.s_addr = INADDR_ANY; 
    if ((bind(socket_fd, (struct sockaddr *)&server, sizeof(struct sockaddr)))== -1) { //sizeof(struct sockaddr) 
     fprintf(stderr, "Binding Failure\n"); 
     exit(1); 
    } 

    if ((listen(socket_fd, BACKLOG))== -1){ 
     fprintf(stderr, "Listening Failure\n"); 
     exit(1); 
    } 

    while(1) { 
     size = sizeof(struct sockaddr_in); 

     if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) { 
      //fprintf(stderr,"Accept Failure\n"); 
      perror("accept"); 
      exit(1); 
     } 

     printf("Server got connection from client %s\n", inet_ntoa(dest.sin_addr)); 
     //buffer = "Hello World!! I am networking!!\n"; 

     if ((num = recv(client_fd, buffer, 10239,0))== -1) { 
      //fprintf(stderr,"Error in receiving message!!\n"); 
      perror("recv"); 
      exit(1); 
     } 

     // num = recv(client_fd, buffer, sizeof(buffer),0); 
     buffer[num] = '\0'; 
     printf("Message received: %s\n", buffer); 
     close(client_fd); 
     return 0; 
     //close(socket_fd); 
    }  
} 

客户:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

#define PORT 3490 

int main(int argc, char *argv[]) 
{ 
    struct sockaddr_in server_info; 
    struct hostent *he; 
    int socket_fd,num; 
    char *buffer; 

    if (argc != 2) { 
     fprintf(stderr, "Usage: client hostname\n"); 
     exit(1); 
    } 

    if ((he = gethostbyname(argv[1]))==NULL) { 
     fprintf(stderr, "Cannot get host name\n"); 
     exit(1); 
    } 

    if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0))== -1) { 
     fprintf(stderr, "Socket Failure!!\n"); 
     exit(1); 
    } 

    memset(&server_info, 0, sizeof(server_info)); 
    server_info.sin_family = AF_INET; 
    server_info.sin_port = htons(PORT); 
    server_info.sin_addr = *((struct in_addr *)he->h_addr); 
    if (connect(socket_fd, (struct sockaddr *)&server_info, sizeof(struct sockaddr))<0) { 
     //fprintf(stderr, "Connection Failure\n"); 
     perror("connect"); 
     exit(1); 
    } 

    buffer = "Hello World!! I am networking!!\n"; 
    if ((send(socket_fd,buffer, sizeof(buffer),0))== -1) { 
     fprintf(stderr, "Failure Sending Message\n"); 
     close(socket_fd); 
     exit(1); 
    } 
    else { 
     printf("Message being sent: %s\n",buffer); 
    } 

    close(socket_fd); 
} 

你的第一个问题是放错地方的括号内。

if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) { 

实际上应该是

if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1) { 

正如你现在拥有它,client_fd将被分配到的accept()-1,因此返回值之间的相等测试的结果永远是零的情况下,的成功。

这是许多程序员避免在if语句中分配的原因之一。如果是这样写的

client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size); 
if (client_fd == -1) { 

然后错误不会发生。

+0

先生,非常感谢你!我得到了错误,但你写了与我一样的声明! :P但我明白我的错误! – ueg1990 2012-07-09 01:39:05

+0

是的,刚刚发现并更新了答案。我复制并粘贴该行,并忘记编辑:) – 2012-07-09 01:39:43

+0

但现在,我有另一个问题!我无法收到完整的讯息! :( 我想发送“Hello World !!我联网!!” – ueg1990 2012-07-09 01:40:16

我在gdb下运行了服务器,并在accept()调用后发现client_fd为0。这是一个无效的套接字fd,所以我看着那行代码,发现右括号是错误的:

if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size)==-1)) { 

应该是:

if ((client_fd = accept(socket_fd, (struct sockaddr *)&dest, &size))==-1) { 

否则,它的第一个,然后做比较将比较分配给client_fd,而您想要分配套接字,然后进行比较。

为了避免这种令人沮丧的错误,通常认为最好的做法是不要在'if'语句中放置任务。我会推荐:

client_fd = accept(...); 
if (client_fd < 0) { ... } 

而且,在客户端,send()调用使用“sizeof(buffer)”。 'buffer'是char *,指针的大小是4(在32位系统上),所以只会发送'Hell'。要发送完整的字符串,请使用“strlen(buffer)”来代替发送金额。

+0

是的,那是错误!谢谢!!我现在收到邮件,但不是完整的邮件 我想发送“Hello World !!我是网络连接!!”但我收到的是“地狱” 任何想法? – ueg1990 2012-07-09 01:44:05

+0

更新了我的答案以解决客户端send()问题。 – saul 2012-07-09 01:45:07

+0

哦,你回答我的第二个问题!非常感谢!!!对此,我真的非常感激!!! – ueg1990 2012-07-09 01:50:18