简体   繁体   English

Winsock2:“听”早回来

[英]Winsock2: “listen” returns early

I'm new to using winsock2 and have put together the following code for a server that I'm trying to use to send a string to a client that I'm running on the same computer (connecting to 127.0.0.1 with the same port as the server is set to listen on). 我是使用Winsock2的新手,并为服务器使用以下代码,该服务器试图将字符串发送到我在同一台计算机上运行的客户端(使用相同端口连接到127.0.0.1)服务器设置为监听)。

I'm using MinGW, if that matters. 我正在使用MinGW,如果那很重要的话。

The problem I'm having is that listen() seems to finish early but returning a success code. 我遇到的问题是listen()似乎提早完成,但返回了成功代码。 This is a problem because then when accept() is called it seems to block forever. 这是一个问题,因为当调用accept()时,它似乎永远阻塞了。 This event happens whether or not I am running the client program, and I have tried running the client program before and after but this doesn't seem to affect it. 无论我是否正在运行客户端程序,都会发生此事件,并且在尝试之前和之后都尝试运行客户端程序,但这似乎并不影响它。

// -1: "Could not initialize WSA."
// -2: "Could not create listener socket."
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <iphlpapi.h>
#include <cstdio>
#define port 0x0ABC
UINT64 trStrLen (char* str)
{
    if (str == NULL) return 0;
    UINT64 pos = 0;
    while (*(str + pos) != '\0') pos++;
    return pos;
};
#include <cstdio>
int main ()
{
    WSADATA wsadata;
    if (WSAStartup(MAKEWORD(2,0),&wsadata)) return -1;
    SOCKET server = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    SOCKADDR_IN sin;
    memset(&sin,0,sizeof(SOCKADDR_IN));
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    sin.sin_addr.s_addr = INADDR_ANY;
    int socksize = sizeof(SOCKADDR);
    while (bind(server,(SOCKADDR*)(&sin),socksize) == SOCKET_ERROR) return -2;
    char* TEMP_TO_SEND = "Billy Mays does not approve.";
    UINT64 TEMP_SEND_LEN = trStrLen(TEMP_TO_SEND);
    printf("Server online.\n");
    while (true)
    {
        printf("Waiting for connections.\n");
        while (listen(server,SOMAXCONN) == SOCKET_ERROR);
        printf("Client requesting connection.\n");
        SOCKET client = accept(server,NULL,NULL);
        printf("Accept is no longer blocking.\n");
        if (client != INVALID_SOCKET)
        {
            printf("Attempting to send information to the client...\n");
            if (send(client,TEMP_TO_SEND,TEMP_SEND_LEN,0) == SOCKET_ERROR) printf("The information wasn't sent properly.\n");
            else printf("The client received the information.\n");
        }
        else printf("Couldn't establish a connection to the client.\n");
    };
};

It's probably something obvious, but I'm not seeing it, so any tips would be helpful. 这可能很明显,但是我没有看到它,因此任何提示都将有所帮助。

listen() isn't a blocking call. listen()不是阻塞调用。 It doesn't do anything to the network. 它对网络没有任何作用。 It just puts the socket into passive listening mode, sets up the backlog queue, and returns. 它只是将套接字置于被动侦听模式,设置了积压队列,然后返回。 It is accept() that is the blocking call: it blocks until an incoming connection has been completed and then returns a socket for it. 它是accept() ,它是阻塞的调用:它阻塞直到输入连接完成,然后为其返回一个套接字。

So you shouldn't be calling listen() in a while loop at all. 因此,您根本不应该在while循环中调用listen()

Same applies to bind() . 同样适用于bind() Call it once. 打电话一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM