在C中为ubuntu绑定到特定IP

发布于 2025-01-02 22:39:31 字数 2892 浏览 2 评论 0原文

您好,我正在尝试制作一个简单的服务器,它从 getaddrinfo() 获取 IP 地址并绑定到它。使用 ifconfig,我发现我想绑定到 wlan0 192.168.2.10 的 IP 地址。不幸的是,我似乎绑定的地址是我的本地设备。由于某种原因,当我初始化 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 路由器为我的子网分配了 IP 地址 192.168.2.10,如果我在网络之外并尝试联系我的服务器,如何找出我的 IP 地址是什么?我假设内部网络 IP 与外部网络 IP 不同......我错了吗?无论如何,这是我的两个问题。

感谢您的帮助!

Hi I am trying to make a simple server that takes in an IP address from getaddrinfo() and binds to it. Using ifconfig, I've found that I have an ip address of wlan0 192.168.2.10 which I would like to bind to. Unfortunately the address I seem to be binding to is my lo device. For some reason when I initialize getaddrinfo("192.168.2.10","3490",&hings,&res); res gets returned to a NULL pointer. I will show off my code bellow.

#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;
}

Now I have some other questions beside the fact that I'm returning null. Since the wifi router has assigned me the ip address 192.168.2.10 for my subnet, how do I find out what my ip address is if I'm outside the network and trying to contact my server? I'm assuming the inside network ip is different from the outside network ip ... am I wrong? Anyways those are my two questions.

Thanks for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

此岸叶落 2025-01-09 22:39:31

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

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

您想要类似的东西:

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

但我个人会使用 while 循环。

This is wrong and is your immediate problem:

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

You want something like:

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

but I would go with a while loop personally.

只为守护你 2025-01-09 22:39:31

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

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

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

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

To your main question, you should just bind to INADDR_ANY. That avoids that whole mess. Also:

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

The %s format specifier is only for C-style strings, it's not for arbitrary binary data. Also, you throw away the return value from recv. There is no other way to know how many bytes you received.

As for finding your dynamic IP address from outside your network, use any of the dozens of IP posting services that assign you a host name and map it to your dynamic IP address.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文