下面的服务器在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;
}到目前为止我尝试过的事情:
either
closesocket(...)是Windows的一部分,如果我决定忽略"Address already in use“错误,accept(...)与Invalid argument一起失败,我只是无意使用
如果有关系的话,我在Windows 10下使用CLion和cygwin。
发布于 2019-09-17 14:46:32
“如果有关系的话,我在Windows 10下使用CLion和cygwin。”
我强烈怀疑这很重要。
当我完全按照您发布的方式编译代码时,它的行为会根据您希望的/预期的行为进行。
当我注释掉setsockopt()调用时,我需要等到TIME_WAIT过期后才能重新绑定相同的address+port,这也是预期的。
我在macOS上使用gcc,所以我怀疑您的编译和/或运行时环境与您的代码不像预期的那样工作有关。如果您没有访问物理Linux机器的权限,如果无法在Windows机器上设置双引导,您可以验证这一点,方法之一是在Digital、AWS或其他云提供商上拆分一个小型Linux实例。
编辑#1
我在一个DO Linux主机上重复了这一点,并且我已经确认了您的原始代码如预期的那样工作。
https://stackoverflow.com/questions/57975704
复制相似问题