【问题标题】:Binding failed : Cannot assign requested address绑定失败:无法分配请求的地址
【发布时间】:2019-12-26 02:38:46
【问题描述】:

第二次运行此服务器代码时,我收到此错误

“绑定失败:无法分配请求的地址”。

我正在使用RE_USEADDR,但仍然面临问题。我知道服务器在使用后没有关闭。

命令行输入:

arg[1]=127.0.0.1,arg[2]=5019

代码

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

void reverse(char*, int, int);

int main(int argc, char* argv[]){
int welcomeSocket, newSocket;
char buffer[1024];
struct sockaddr_in serverAddr;
struct sockaddr_storage serverStorage;
socklen_t addr_size;
int val=1;

bzero((char*)&serverAddr,sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(atoi(argv[2]));
serverAddr.sin_addr.s_addr = htonl(argv[1]);
if((welcomeSocket = socket(AF_INET, SOCK_STREAM, 0))==-1){
        perror("socket err");
        exit(1);}


memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);

setsockopt(welcomeSocket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int));

if(bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr))<0){
    perror("Binding failed\n");
    exit(1);}

if(listen(welcomeSocket,5)==0)
    printf("Listening\n");
else
    printf("Error\n");

while(1){
    printf("1");
    addr_size = sizeof(serverStorage);
    newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);

    recv(newSocket, buffer, 1024, 0);
    printf("Data received: %s",buffer);

    reverse(buffer, 0, strlen(buffer)-1);
    send(newSocket,buffer,13,0);

    close(newSocket);
}
close(welcomeSocket);
return 0;
}

我希望它每次都能正常工作,而不管它的 ip 和端口。

【问题讨论】:

  • 你没有检查recv的返回。无法保证在单个数据包中发送完整的缓冲区。
  • 另外,你在一个不能保证为空终止的缓冲区上执行 strlen。
  • 我正在使用RE_USEADDR,但仍然遇到问题" - 我相信是SO_REUSEADDR。另请参阅How do SO_REUSEADDR and SO_REUSEPORT differ? 和朋友。您可能也正在重新启动很快。在这种情况下,减少 SO_LINGER。延迟有助于在传输到旧的 [dead] 服务器的过程中客户端关闭。

标签: c linux sockets server command-line-arguments


【解决方案1】:

htonl 函数需要一个 32 位整数值。相反,您传递的是字符串的地址,因此您实际上是在尝试将此地址转换为网络字节顺序中的 32 位值作为 IP 地址。

您希望将字符串传递给 inet_addr,它将 IPv4 地址的字符串表示形式转换为网络字节顺序的 32 位值。

serverAddr.sin_addr.s_addr = inet_addr(argv[1]);

【讨论】:

    【解决方案2】:

    当你退出程序时,套接字并没有优雅地关闭。我建议使用信号中断处理程序并关闭welcomeSocket。

    void sigintHandler(int sig_num) {
    close(welcomeSocket);
    }
    
    int main(){
    signal(SIGINT, sigintHandler);
    ...
    ...
    your code
    while (1) {
      //code
    }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-16
      • 2017-04-13
      • 2021-03-07
      • 2012-12-25
      • 2019-10-11
      • 1970-01-01
      • 1970-01-01
      • 2020-08-24
      相关资源
      最近更新 更多