c - 套接字编程 :using inet_addr() and ip address isn't be hardcoded

标签 c linux sockets network-programming

我在我的程序中使用 inet_addr() 但我不希望 ip 地址被硬编码。 所以我尝试 inet_addr(argv[1]) 但我的程序无法获取 IP 地址。谁能帮帮我?

服务器

int main(int argc,char *argv[])
{
    char str[100];                                         // declare necessary variables
    int listen_fd, comm_fd;
    struct sockaddr_in servaddr;
    struct sockaddr_storage serverStorage;
    socklen_t addr_size;
    char welcome[100];
    char i[100];
    char incorrectnum[100];
    char line[512],line1[500],line2[500],line3[500],line4[500],line5[500];
    FILE *fp;
    char ch;
    char str2[100];
    char *file_path = "FILE.txt";


    listen_fd = socket(AF_INET, SOCK_STREAM, 0);            //create a socket
    if (listen_fd == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    strcpy(str2,argv[1]);

    printf("%s\n",str2 );


    servaddr.sin_family = AF_INET;                          // prepare the sockaddr_in structure.
    servaddr.sin_port = htons(1999);
    servaddr.sin_addr.s_addr = inet_addr(str2);
    memset(servaddr.sin_zero, '\0', sizeof servaddr.sin_zero);  


    if(bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0){ //bind a name to a socket
        //print the error message
        perror("bind failed. Error");
        return 1;
    }
    puts("bind done");

    listen(listen_fd, BACKLOG);                             //listening for  incomming connection
    puts("Waiting for incoming connections...");

    addr_size = sizeof serverStorage;
    comm_fd = accept(listen_fd, (struct sockaddr *)&serverStorage, &addr_size);
    if (comm_fd < 0){
        perror("accept failed");
        return 1;
    }
    puts("Connection accepted");

    printf("***___WELCOME TO MY SERVER___***\n");
    bzero(welcome, 100);  
    strcpy(welcome,"***___WELCOME TO MY SERVER___***");

    send(comm_fd, welcome,100, 0);
.....
    }

客户

int main(int argc,char *argv[]){
    int sockfd, linenum;               //declare necessary variables 
    char str[100];
    char i[100];
    char server_respose[2000],line1[1000],line2[1000],line3[1000],line4[1000],line5[1000];
    char welcome[100];
    struct sockaddr_in servaddr;               // socket address struct


    if(argc != 2)
    {
        printf("\n Usage: %s <ip of server> \n",argv[0]);
        return 1;
    } 

    sockfd = socket(AF_INET, SOCK_STREAM, 0);  //create a socket with the appropriate protocol
    if (sockfd == -1)
    {
        printf("Could not create socket\n");
    }
    puts("Socket created");

    servaddr.sin_family = AF_INET;             //IPv4 
    servaddr.sin_port = htons(1999);           

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

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

    if(connect(sockfd,(struct sockaddr *)&servaddr, sizeof(servaddr))<0){
        perror("connect failed. Error");
        return 1;                                      // attempt to connect to a socket
    }

    printf("--You are connected to the server--\n");

        recv(sockfd, welcome, 100, 0)
...
}

最佳答案

inet_addr 应避免在新程序中使用,而应使用(在其他方法中)getaddrinfo。此方法与 IPv6 兼容,通常更易于使用。

linux.die.net 页面有一个很好的客户端/服务器通信代码示例,它可以满足您的需求:http://linux.die.net/man/3/getaddrinfo (以下重要部分转载)

服务器程序

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

int main(int argc, char *argv[]) { // port
    struct addrinfo hints;
    struct addrinfo *result, *rp;
    int sfd, s;

    if (argc != 2) {
        fprintf(stderr, "Usage: %s port\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
    hints.ai_flags = AI_PASSIVE;    /* For wildcard IP address */
    hints.ai_protocol = 0;          /* Any protocol */
    hints.ai_canonname = NULL;
    hints.ai_addr = NULL;
    hints.ai_next = NULL;

    s = getaddrinfo(NULL, argv[1], &hints, &result);
    if (s != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
        exit(EXIT_FAILURE);
    }

    /* getaddrinfo() returns a list of address structures.
       Try each address until we successfully bind(2).
       If socket(2) (or bind(2)) fails, we (close the socket
       and) try the next address. */

    for (rp = result; rp != NULL; rp = rp->ai_next) {
        sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
        if (sfd == -1)
            continue;

        if (bind(sfd, rp->ai_addr, rp->ai_addrlen) == 0)
            break;                  /* Success */

        close(sfd);
    }

    if (rp == NULL) {               /* No address succeeded */
        fprintf(stderr, "Could not bind\n");
        exit(EXIT_FAILURE);
    }

    freeaddrinfo(result);           /* No longer needed */

    // ...snip - not relevant to this question
}

客户端程序

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

int main(int argc, char *argv[]) { // host port
    struct addrinfo hints;
    struct addrinfo *result, *rp;
    int sfd, s, j;

    if (argc < 3) {
        fprintf(stderr, "Usage: %s host port msg...\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    /* Obtain address(es) matching host/port */

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_UNSPEC;    /* Allow IPv4 or IPv6 */
    hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
    hints.ai_flags = 0;
    hints.ai_protocol = 0;          /* Any protocol */

    s = getaddrinfo(argv[1], argv[2], &hints, &result);
    if (s != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
        exit(EXIT_FAILURE);
    }

    /* getaddrinfo() returns a list of address structures.
       Try each address until we successfully connect(2).
       If socket(2) (or connect(2)) fails, we (close the socket
       and) try the next address. */

    for (rp = result; rp != NULL; rp = rp->ai_next) {
        sfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
        if (sfd == -1)
            continue;

        if (connect(sfd, rp->ai_addr, rp->ai_addrlen) != -1)
            break;                  /* Success */

        close(sfd);
    }

    if (rp == NULL) {               /* No address succeeded */
        fprintf(stderr, "Could not connect\n");
        exit(EXIT_FAILURE);
    }

    freeaddrinfo(result);           /* No longer needed */

    // ...snip - not relevant to this question

    exit(EXIT_SUCCESS);
}

关于c - 套接字编程 :using inet_addr() and ip address isn't be hardcoded,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34382351/

相关文章:

c - 使用递归打印控制台 "picture"

python - 接收器的scapy?

c++ - 为什么同一台服务器的两个版本表现不同?

sockets - 如何进行 TCP 打洞?

java - 通过套接字从服务器向 Android 客户端发送非常大的字符串

c - 子进程之间的 UNIX 管道

c - 从函数返回 struct*

c - 如何处理 win32 可执行资源?

python - 未安装 PyQt5 模块 "QtQuick"

linux - 更改 Qsys 设计以运行最新版本的 uClinux