接受的套接字上出现“错误的文件描述符”错误

时间:2021-06-05 20:30:38

I'm trying to get into network programming and have been following a guide on sockets. I wrote a simple Windows TCP server and client in C, but cannot seem to get them working. The second the client connects, the server throws a 'Bad file descriptor' error and closes. I don't understand how the file descriptor that was just created by accept() can be bad. I have done research on this and have only found people who had closed the file before reading it, which I did not.

我正在尝试进入网络编程,并一直关注套接字指南。我在C中编写了一个简单的Windows TCP服务器和客户端,但似乎无法让它们正常工作。客户端连接的第二个,服务器抛出'错误的文件描述符'错误并关闭。我不明白accept()创建的文件描述符是如何坏的。我已经对此进行了研究,并且只找到了在阅读之前关闭文件的人,我没有。

Here is the code :

这是代码:

SERVER

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>

int main(int argc, char *argv[])
{
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,0), &WSAData);

    SOCKET sock, newsock;
    int portno, clilen;
    char buffer[256];
    SOCKADDR_IN serv_addr, cli_addr;
    int n;

    sock = socket(AF_INET, SOCK_STREAM, 0);

    if (sock < 0)
    {
        perror("Error opening socket");
        exit(1);
    }

    memset((char *) &serv_addr, 0, sizeof(serv_addr));
    portno = 5001;

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);

    if (bind(sock, (SOCKADDR *) &serv_addr, sizeof(serv_addr)) < 0)
    {
        perror("Eror on binding");
        exit(1);
    }

    listen(sock, 5);
    clilen = sizeof(cli_addr);

    newsock = accept(sock, (SOCKADDR *) &cli_addr, &clilen);
    if (newsock < 0)
    {
        perror("Error on accept");
        exit(1);
    }

    memset(buffer, 0, 256);
    n = read(newsock, buffer, 255);

    if (n < 0)
    {
        perror("Error reading from socket");
        exit(1);
    }

    printf("Here is the message : %s\n", buffer);

    n = write(newsock, "I got your message", 18);
    if (n < 0) 
    {
        perror("Error writing to socket");
        exit(1);
    }

    WSACleanup();
    return 0;
}

CLIENT

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>

int main(int argc, char *argv[])
{
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,0), &WSAData);

    SOCKET sock;
    int portno, n;
    SOCKADDR_IN serv_addr;
    HOSTENT *server;
    char buffer[256];

    if (argc < 3)
    {
        fprintf(stderr, "Usage : %s hostname port\n", argv[0]);
        exit(0);
    }

    portno = atoi(argv[2]);
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0)
    {
        perror("Error opening socket\n");
        exit(1);
    }

    server = gethostbyname(argv[1]);

    if (server == NULL)
    {
        perror("Error, no such host");
        exit(1);
    }

    memset((char *) &serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    memcpy((char *) &serv_addr.sin_addr.s_addr, (char *) server->h_addr, server->h_length);
    serv_addr.sin_port = htons(portno);

    if (connect(sock, (SOCKADDR *) &serv_addr, sizeof(serv_addr)) < 0)
    {
        perror("Error connecting to server");
        exit(1);
    }

    printf("Please enter your message : ");
    memset(buffer, 0, 256);
    fgets(buffer, 255, stdin);

    n = write(sock, buffer, strlen(buffer));
    if (n < 0)
    {
        perror("Error writing to socket");
        exit(1);
    }

    memset(buffer, 0, 256);
    n = read(sock, buffer, 255);

    if (n < 0)
    {
        perror("Error reading from socket");
        exit(1);
    }

    printf("%s\n", buffer);

    WSACleanup();
    return 0;
}

...And here's the output just in case :

......以下是输出以防万一:

C:\...myfolder>server
*here it does nothing until I start the client with "client 127.0.0.1 5001" in another window*
Error reading from socket: Bad file descriptor

Do you see what is wrong with my code? Thanks in advance for your help!

你看到我的代码出了什么问题吗?在此先感谢您的帮助!

1 个解决方案

#1


3  

I would put this in a comment, but try using the recv() function instead of read(). This is because read() doesn't call into the Socket API, so as far as Windows is concerned, the file descriptor isn't valid.

我会把它放在注释中,但尝试使用recv()函数而不是read()。这是因为read()不会调用Socket API,所以就Windows而言,文件描述符无效。

On the same note, in your client you should use send() instead of write().

同样,在您的客户端中,您应该使用send()而不是write()。

#1


3  

I would put this in a comment, but try using the recv() function instead of read(). This is because read() doesn't call into the Socket API, so as far as Windows is concerned, the file descriptor isn't valid.

我会把它放在注释中,但尝试使用recv()函数而不是read()。这是因为read()不会调用Socket API,所以就Windows而言,文件描述符无效。

On the same note, in your client you should use send() instead of write().

同样,在您的客户端中,您应该使用send()而不是write()。