2015-09-26 124 views
0

我正在C写一个双向聊天,但我真正想做的是让聊天服务器在启动时打印主机的IP地址。我的代码到目前为止是这样的:打印我的TCP TCP服务器C

#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通过主机名查找ip然后打印?还有其他建议吗?

感谢

+1

你可以循环所有的接口并打印每个ip。也许过滤掉lo0这是127.1。 –

+0

http://stackoverflow.com/questions/9860390/c-get-ip-for-listening-server – kaylum

+0

ott,什么会被视为我的外部IP? eth0通常?特别是我想让服务器说出它正在监听的IP,这样我就可以告诉某人启动聊天客户端的哪个ip来连接。 – tadamhicks

回答

0

我找到了解决办法。现在我的代码看起来是这样的:

#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指南中,但我还没有找到如何做到这一点呢。