不接收TCP客户端/服务器程序中的消息

时间:2012-07-09 01:09:02

标签: c client-server

我正在尝试实现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);   
}

2 个答案:

答案 0 :(得分:1)

我在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)”代替要发送的金额。

答案 1 :(得分:0)

你的第一个问题是错误的括号。

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) {

然后就不会发生错误。