setsockopt()不会解除绑定

时间:2019-09-17 13:47:20

标签: c server

C中的以下服务器无法正常工作。第一次运行时,不会发生任何问题。下次您运行它时,它将无法绑定。不管setsockopt(...)是否成功,你们中的某些人可能都将其标记为重复的问题的解决方案也不起作用。

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


#define PORT 8080
#define SA struct sockaddr

int main() {

    int sockfd, connfd;
    struct sockaddr_in servaddr, cli;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd == -1) puts("Socket creation failed."), exit(0);
    else puts("Socket created.");

    const int       optVal = 1;
    const socklen_t optLen = sizeof(optVal);
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optVal, optLen);

    servaddr.sin_family = AF_INET, servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if (bind(sockfd, (SA *) &servaddr, sizeof(servaddr))) {
        puts("Bind failed.");
        shutdown(sockfd, 2);
        return 12;
    }
    else puts("Bound.");

    if(listen(sockfd, 5)) puts("Listen failed."), exit(2);
    else puts("Listening: ");
    int len = sizeof(cli);

    connfd = accept(sockfd, (SA*)&cli, &len);
    if(connfd < 0) puts("Connection failed."), exit(3);
    else puts("Accepted.");

    close(connfd);
    return 0;
}

到目前为止我已经尝试过的事情:

  1. 使用setsockopt(...)无效
  2. shutdown(...)也不起作用
  3. closesocket(...)是Windows API的一部分,我只是无意使用
  4. 如果我决定忽略“ Address already in use”错误,则accept(...)失败,并显示Invalid argument

如果有问题,我将在Windows 10下将CLion与cygwin一起使用。

1 个答案:

答案 0 :(得分:1)

“如果有关系,我将在Windows 10下将cygwin与CLion一起使用”。

我强烈怀疑这很重要。

当我完全按照您发布的代码编译代码时,它的行为将根据您的期望/预期行为。

当我注释掉setsockopt()呼叫时,我需要等到TIME_WAIT到期后才能重新绑定相同的地址和端口,这也是预期的。

我在macOS上使用gcc,因此我怀疑您的编译和/或运行时环境与您的代码无法正常工作有关。如果您无权访问物理Linux计算机,并且无法在您拥有的Windows计算机上设置双重引导,则可以验证此方法的一种方法是在Digital Ocean上启动一个小型Linux实例, AWS或其他一些云提供商。

编辑#1

我在DO Linux主机上重复了此操作,并确认您的原始代码可以正常工作。