【问题标题】:Bind to a specific IP in C for ubuntu为 ubuntu 绑定到 C 中的特定 IP
【发布时间】:2012-02-05 03:47:39
【问题描述】:

您好,我正在尝试制作一个简单的服务器,它从 getaddrinfo() 获取 IP 地址并绑定到它。使用 ifconfig,我发现我想要绑定的 IP 地址为 wlan0 192.168.2.10。不幸的是,我似乎绑定的地址是我的 lo 设备。由于某种原因,当我初始化 getaddrinfo("192.168.2.10","3490",&hings,&res); res 被返回到一个 NULL 指针。我将在下面展示我的代码。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <signal.h>

#define MAXDATASIZE 500;

int main(int argc, char *argv[]){
    // dealing with client socket
    struct sockaddr_storage their_addr;
    socklen_t addr_size;
    // server socket
    struct addrinfo serverSide,*serverInfo,*sortIP;
    int optValRet;
    int listenSock, newSock;
    // this is for reading in information
    char buf[501];
    char point[INET6_ADDRSTRLEN];
    char compare[INET6_ADDRSTRLEN] = "192.168.2.10";
    // this is for handeling child processes and signals
    struct sigaction sa;
    sa.sa_handler = NULL;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if(sigaction(SIGCHLD, &sa, NULL) == -1){
        printf("We have a problem, sigaction is not working.\n");
        perror("\n");
        exit(1);    
    }   
    // this sets up addrinfo
    memset(&serverSide, 0, sizeof serverSide);
    serverSide.ai_family = AF_UNSPEC;
    serverSide.ai_socktype = SOCK_STREAM;
    serverSide.ai_flags = INADDR_ANY;
    // set up the address
    if(getaddrinfo("192.168.2.10","3490",&serverSide,&serverInfo)!=0){
        printf("get addr not success\n");
        perror("\n");
        return 1;
    }

    printf("Got address lists\n");

    for(sortIP = serverInfo; sortIP = sortIP->ai_next; sortIP != NULL){

        if((listenSock = socket(sortIP->ai_family, sortIP->ai_socktype, sortIP->ai_protocol))==-1){
            continue;
        }
        if(setsockopt(listenSock,SOL_SOCKET,SO_REUSEADDR,&optValRet,sizeof(int))==-1){
            perror("\n");
            exit(1);
        }
        if(bind(listenSock,sortIP->ai_addr,sortIP->ai_addrlen) == -1 ){
            perror("\n");
            close(listenSock);
            continue;       
        }
        break;
    }
    if(sortIP == NULL){printf("sort ip is null.");}
    inet_ntop(sortIP->ai_family,sortIP->ai_addr,point,sizeof point);
    printf("Tell the clients connect to ip address %s on port 3490\n",point);
    listen(listenSock, 10);
    addr_size = sizeof their_addr;
    newSock = accept(listenSock,(struct sockaddr *)&their_addr,&addr_size);
    recv(newSock, buf, 500, 0);
    printf("%s\n",buf);
    close(listenSock);
    close(newSock);
    freeaddrinfo(serverInfo);
    return 0;
}

除了返回 null 之外,我还有其他一些问题。由于 wifi 路由器已为我的子网分配了 192.168.2.10 的 IP 地址,如果我在网络之外并试图联系我的服务器,我该如何找出我的 IP 地址?我假设内部网络 ip 与外部网络 ip 不同......我错了吗?无论如何,这是我的两个问题。

感谢您的帮助!

【问题讨论】:

  • 为什么我被否决了?我还能在哪里问这个问题?

标签: c sockets unix networking bind


【解决方案1】:

这是错误的,是您的直接问题:

for (sortIP = serverInfo; sortIP = sortIP->ai_next; sortIP != NULL)

你想要这样的东西:

for (sortIP = serverInfo; sortIP != NULL; sortIP = sortIP->ai_next)

但我个人会使用 while 循环。

【讨论】:

    【解决方案2】:

    对于您的主要问题,您应该只绑定到 INADDR_ANY。这避免了整个混乱。另外:

    recv(newSock, buf, 500, 0);
    printf("%s\n",buf);
    

    %s 格式说明符仅适用于 C 风格的字符串,不适用于任意二进制数据。此外,您丢弃了来自recv 的返回值。没有其他方法可以知道您收到了多少字节。

    至于从网络外部查找您的动态 IP 地址,请使用为您分配主机名并将其映射到您的动态 IP 地址的数十种 IP 发布服务中的任何一种。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-14
      • 2012-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-05
      • 2011-04-15
      相关资源
      最近更新 更多