0

我正在用 C 编写双向聊天,但我真正想做的是让聊天服务器在启动时打印主机的 ip。到目前为止,我的代码如下所示:

#include<stdio.h> //printf
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>

#define PORT 8888   //The port on which to listen for incoming data
void error(char *msg)
{
    perror(msg);
    exit(1);
}
int main(void)
{
    struct sockaddr_in serv_addr, cli_addr;
    int sockfd, newsockfd, n;
    socklen_t cli_len;
    char buffer[512];
    char message[512];

    //create a socket
    sockfd=socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR OPENING SOCKET");

    // zero out the structure
    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    serv_addr.sin_addr.s_addr = INADDR_ANY;

    //bind socket to port
    if (bind(sockfd, (struct sockaddr *) &serv_addr,
        sizeof(serv_addr)) < 0)
            error("ERROR ON BINDING");

    //keep listening for data
    //inet_ntoa(serv_addr.sin_addr)
    inet_ntop(AF_INET, &serv_addr.sin_addr.s_addr, buffer, sizeof(serv_addr));
    listen(sockfd,5);
    printf("Listening on ip %s and port %d\n", buffer, ntohs(serv_addr.sin_port));
    while(1)
    {
        cli_len = sizeof(cli_addr);
        newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &cli_len);
        if (newsockfd < 0) error("ERROR ON ACCEPT");

        while(1)
        { 
            bzero(buffer,512);
            n = read(newsockfd,buffer,511);
            if(n < 0) error("ERROR READING FROM SOCKET");
            printf("Friend: %s\n" , buffer);

            //now reply
            printf("Please enter the message: ");
            bzero(buffer,512);
            fgets(buffer,511,stdin);
            n = write(newsockfd,buffer, strlen(buffer));
            if (n < 0) error("ERROR writing to socket");
        }
        close(newsockfd);
    }
    close(sockfd);
    return 0;
}

目前,当我制作并运行它时,它会立即打印

Listening on ip 0.0.0.0 and port 8888

这真的应该很简单。我意识到它绑定到所有接口,所以 0.0.0.0 是准确的 ip。

有没有办法让它显示主机IP?我是否正在查看 ping DNS 以按主机名查找 ip 然后打印?还有其他建议吗?

谢谢

4

1 回答 1

1

我找到了解决方案。我的代码现在看起来像这样:

#include<stdio.h> //printf
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netdb.h>

#define PORT 8888   //The port on which to listen for incoming data
void error(char *msg)
{
    perror(msg);
    exit(1);
}
int main(void)
{
    struct sockaddr_in serv_addr, cli_addr;
    int sockfd, newsockfd, n;
    socklen_t cli_len;
    char buffer[512];
    char message[512];
    char sZhostName[255];
    gethostname(sZhostName,255);
    struct hostent *host_entry;
    host_entry = gethostbyname(sZhostName);


    //create a socket
    sockfd=socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR OPENING SOCKET");

    // zero out the structure
    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    serv_addr.sin_addr.s_addr = INADDR_ANY;

    //bind socket to port
    if (bind(sockfd, (struct sockaddr *) &serv_addr,
        sizeof(serv_addr)) < 0)
            error("ERROR ON BINDING");

    //keep listening for data
    listen(sockfd,5);
    printf("Listening on ip %s and port %d\n", inet_ntoa (*(struct in_addr *)*host_entry->h_addr_list), ntohs(serv_addr.sin_port));
    while(1)
    {
        cli_len = sizeof(cli_addr);
        newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &cli_len);
        if (newsockfd < 0) error("ERROR ON ACCEPT");

        while(1)
        { 
            bzero(buffer,512);
            n = read(newsockfd,buffer,511);
            if(n < 0) error("ERROR READING FROM SOCKET");
            printf("Friend: %s\n" , buffer);

            //now reply
            printf("Please enter the message: ");
            bzero(buffer,512);
            fgets(buffer,511,stdin);
            n = write(newsockfd,buffer, strlen(buffer));
            if (n < 0) error("ERROR writing to socket");
        }
        close(newsockfd);
    }
    close(sockfd);
    return 0;
}

我使用了这篇文章:https ://suite.io/guy-lecky-thompson/7sd21g

有关于 getaddrinfo() 替换 gethostname()/gethostbyname() 方法的建议,包括在著名的 Beej 指南中,但我还没有找到如何做到这一点。

于 2015-09-27T15:53:22.960 回答