2016-09-18 2 views
2

У меня есть ноутбук, работающий под Windows 10, и intalled ubuntu в Oracle VM Virtualbox Machine. У меня есть следующий исходный код сервера и клиента. Сначала я запускаю сервер, а затем клиент. Но это дало мне связь. Пробовал netstat -ntlp, затем выяснил, что на самом деле нет порта, который прослушивает конкретный порт, который я набрал.C Соединение с клиентским сервером Отказано

enter image description here

server.c

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<sys/utsname.h> 
#include<sys/types.h> 
#include<sys/socket.h> 
#include<netinet/in.h> 
#include<arpa/inet.h> 
#include<netdb.h> 
#include<unistd.h> 

int _GetHostName(char *buffer, int lenght); 

const char MESSAGE[]="Hello, World!\n"; 
const int BACK_LOG=5; 

int main(int argc, char *argv[]){ 
    int serverSocket=0, on=0, port=0, status=0, childPid=0; 
    struct hostent *hostPtr=NULL; 
    char hostname[80]=""; 
    struct sockaddr_in serverName={0}; 

    if(2!= argc){ 
     fprintf(stderr, "Usage : %s <port>\n", argv[0]); 
     exit(1); 
    } 
    port=atoi(argv[1]); 
    serverSocket=socket(PF_INET,SOCK_STREAM, IPPROTO_TCP); 
    if(-1==serverSocket){ 
     perror("socket()"); 
     exit(1); 
    } 

    on=1; 
    status=setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on)); 
    if(-1==status){ 
     perror("setsockopt(...,SO_REUSEADDRE,...)"); 
    } 

    { 
     struct linger linger={0}; 
     linger.l_onoff=1; 
     linger.l_linger=30; 
     status=setsockopt(serverSocket, SOL_SOCKET, SO_LINGER, (const char*)&linger, sizeof(linger)); 
     if(-1==status){ 
      perror("setsockopt(...,SO_LINGER,...)"); 
     } 
    } 

    status=_GetHostName(hostname, sizeof(hostname)); 
    if(-1==status){ 
     perror("_GetHostName()"); 
     exit(1); 
    } 

    hostPtr=gethostbyname(hostname); 
    if(NULL==hostPtr){ 
     perror("gethostbyname()"); 
     exit(1); 
    } 

    (void)memset(&serverName,0,sizeof(serverName)); 
    (void)memcpy(&serverName.sin_addr, hostPtr->h_addr,hostPtr->h_length); 

    serverName.sin_family=AF_INET; 
    serverName.sin_port=htons(port); 

    status=bind(serverSocket, (struct sockaddr*)&serverName,sizeof(serverName)); 
    if(-1==status){ 
     perror("bind"); 
     exit(1); 
    } 


    status=listen(serverSocket, BACK_LOG); 
    if(-1==status){ 
     perror("listen()"); 
     exit(1); 
    } 

    for(;;){ 
     struct sockaddr_in clientName={0}; 
     int slaveSocket, clientLength=sizeof(clientName); 

     (void)memset(&clientName,0,sizeof(clientName)); 

     slaveSocket=accept(serverSocket,(struct sockaddr*)&clientName, & clientLength); 
     if(-1==slaveSocket){ 
      perror("accept()"); 
      exit(1); 
     } 

     childPid=fork(); 

     switch(childPid){ 
      case -1:perror("fork()"); 
      exit(1); 
      case 0: close(serverSocket); 
      if(-1==getpeername(slaveSocket, (struct sockaddr*)&clientName, &clientLength)){ 
       perror("getpeername()"); 
      }else{ 
       printf("Connection request from %s \n", inet_ntoa(clientName.sin_addr)); 
      } 

      /* 
       Server Application specific code here 
       response to client 
      */ 
      write(slaveSocket,MESSAGE,strlen(MESSAGE)); 
      close(slaveSocket); 
      exit(0); 
      default:close(slaveSocket); 
     } 
    } 
    return 0; 
} 

int _GetHostName(char *buffer,int length){ 
    struct utsname sysname={0}; 
    int status=0; 

    status=uname(&sysname); 
    if(-1!=status){ 
     strncpy(buffer,sysname.nodename,length); 
    } 
    return(status); 
} 

client.c

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <netdb.h> 
#include <string.h> 

int main(int argc, char *argv[]){ 
    int clientSocket, remotePort, status=0; 
    struct hostent *hostPtr=NULL; 
    struct sockaddr_in serverName={0}; 
    char buffer[256]=""; 
    char *remoteHost=NULL; 

    if(3!=argc){ 
     fprintf(stderr, "Usage: %s <serverHost> <serverPort> \n",argv[0]); 
     exit(1); 
    } 
    remoteHost=argv[1]; 
    remotePort=atoi(argv[2]); 
    clientSocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); 
    if(-1==clientSocket){ 
     perror("socket()"); 
     exit(1); 
    } 

    hostPtr=gethostbyname(remoteHost); 
    if(NULL==hostPtr){ 
     hostPtr=gethostbyaddr(remoteHost,strlen(remoteHost), AF_INET); 
     if(NULL==hostPtr){ 
      perror("Error resolving server address "); 
      exit(1); 
     } 
    } 
    serverName.sin_family=AF_INET; 
    serverName.sin_port=htons(remotePort); 
    (void)memcpy(&serverName.sin_addr,hostPtr->h_addr,hostPtr->h_length); 
    status=connect(clientSocket,(struct sockaddr*)&serverName,sizeof(serverName)); 
    if(-1==status){ 
     perror("connect()"); 
     exit(1); 
    } 
    //CLIENT SPECIFIC HERE 

    while(0 < (status=read(clientSocket, buffer,sizeof(buffer)-1))) 
     printf("%d: %s", status, buffer); 
     if(-1==status)perror("read()"); 
     close(clientSocket); 
     return 0; 

} 

ответ

0

Только что понял. В коде нет проблем. Причина, по которой я получил ошибку, особенно в следующей строке, заключается в том, что, поскольку я установил ubuntu в виртуальном ящике, я изменил имя устройства ubuntu без изменения etc/hosts.

hostPtr=gethostbyname(hostname); 
if(NULL==hostPtr){ 
    perror("gethostbyname()"); 
    exit(1); 
} 
2

Как вы можете увидеть в консоли сервера, вызов gethostbyname не удается. Эта функция устанавливает h_errno, а не errno, поэтому вы не можете использовать perror для вывода ошибки. Вот почему вы видите, что это требует «успеха».

Я не вижу смысла использовать gethostbyname здесь, хотя большинство серверов по умолчанию используют INADDR_ANY, когда адрес не указан пользователем.

+0

Думаю, вы имеете в виду эту строку 'hostPtr = gethostbyname (hostname); if (NULL == hostPtr) { perror ("gethostbyname()"); выход (1); } 'но какой должен быть правильный путь? – beginner

1

Как уже указывал Джони, ваша программа не работает в gethostbyname() на сервере server.c, а затем завершается. Поэтому ни один порт не привязан, так как ваша программа больше не работает.

Только не используйте функцию gethostbyname(), если это на самом деле не нужно, и установить sin_addr непосредственно, как в одном из следующих примеров:

// let the kernel fill in the address of your interface for you automatically 
serverName.sin_addr.s_addr = htonl(INADDR_ANY); 

// use a loopback address (127.0.0.1) = localhost 
serverName.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 

// use whatever address you like 
serverName.sin_addr.s_addr = inet_addr("127.1.1.1"); 

Не забудьте удалить l ине

memcpy(&serverName.sin_addr, hostPtr->h_addr,hostPtr->h_length); 

в server.c при установке sin_addr как в приведенных выше примерах.