【问题标题】:Bind failed : Bad file descriptor绑定失败:错误的文件描述符
【发布时间】:2015-09-09 00:05:49
【问题描述】:

我是套接字编程的新手,在这里我试图设置一个简单的服务器套接字并监听它。这是我的代码。

 int server_socket, client_socket, sent;
    size_t len;
    struct sockaddr_in server, client;
    char msg[] = "Hello to the world of socket programming";
    server_socket == socket(AF_INET, SOCK_STREAM, 0);

    if(server_socket == -1){
        perror("Socket creation failed: ");
        exit(-1);
    }

    //define server
    server.sin_family = AF_INET;
    server.sin_port = htons(10000);
    server.sin_addr.s_addr = INADDR_ANY;
    memset(&server.sin_zero, '\0', 8);


    len = sizeof(struct sockaddr_in);

    if((bind(server_socket, (struct sockaddr*)&server, len)) == -1){
        perror("Bind failed: ");
        exit(-1);
    }

    if(listen(server_socket, 5) == -1){
        perror("Listen failed: ");
        exit(-1);
    }

    while(true){

        if((client_socket = accept(server_socket, (struct sockaddr *)&client, (socklen_t *)&len)) == -1){

            perror("Accept failed: ");
            exit(-1);
        }

        sent = send(client_socket, msg, strlen(msg), 0);

        printf("Sent %d byte to client: %s\n", sent, inet_ntoa(client.sin_addr));

        close(client_socket);

    }

我一直在努力

Bind Failed : Bad file descriptor

但是我的文件描述符完全按照 beej 指南。有什么帮助吗?

【问题讨论】:

  • 这一行:memset(&server.sin_zero, '\0', 8); 非常“不确定”。更好(在 'server' `memset(&server, '\0', sizeof(server) 中设置任何字段之前);并删除当前对 memset() 的调用
  • 您是否#include了所有必要的头文件?发布的代码缺少该信息。需要:stdio.h stdlib.h sys/types.h sys/socket.h netinet/in.h arpa/inet.h 可能还有其他一些。您是否在启用所有警告的情况下编译了代码? (对于 gcc,至少使用:-Wall -Wextra -pedantic

标签: c++ c sockets


【解决方案1】:

这是你的问题:

server_socket == socket(AF_INET, SOCK_STREAM, 0);

您没有为server_socket 分配任何内容。您将它与socket 的返回值进行比较。你需要这样做:

server_socket = socket(AF_INET, SOCK_STREAM, 0);

由于您正在侦听 TCP 套接字,因此您还需要这样做:

int option=1;
setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&option,sizeof(option));

如果应用在短时间内被杀死并重新启动,这将防止应用出现“地址已在使用”错误。

【讨论】:

  • 感谢您的帮助,但现在我遇到 Bind failed: : Address already in use
  • 在我的应用程序中,我需要用户使用特定端口号(如 app c 2345 或 app s 2341)明确地作为客户端或服务器运行程序。我还需要使用 setsockopt ?
  • 只有服务端需要。你可以在调用listen之前设置SO_REUSEADDR
【解决方案2】:

好像是笔误造成的:

server_socket == socket(AF_INET, SOCK_STREAM, 0);

应该是:

server_socket = socket(AF_INET, SOCK_STREAM, 0);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-01
    • 2011-09-08
    相关资源
    最近更新 更多