2017-04-05 1 views
0

別のリモートデバイスから作成したローカルUNIXサーバーに接続しようとしています。サーバーが起動し、指定したポートをリッスンします。私もそのポートを開くために新しいファイアウォールルールを追加しましたが、私のクライアントは接続できません。それがエラー接続がここ新しいファイアウォールルールを追加した後でも接続が拒否されました

は私のサーバーコード

int main() { 
    int fd, i,svclient,rval,msg; 
    int clients[10], num_clients; 
    fd_set read_set,write_set; 
    char buf[100]; 

    struct sockaddr_in addr; 

    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { 
    perror("socket error"); 
    exit(-1); 
    } 


    bzero((char *) &addr, sizeof(addr)); 
    addr.sin_family = AF_INET; 
    addr.sin_addr.s_addr = INADDR_ANY; 
    addr.sin_port = htons(4001); 

    //strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)-1); 
    //strcpy(addr.sun_path, NAME); 

    if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { 
    perror("bind error"); 
    exit(-1); 
    } 
    printf("Bind complet...\n"); 

    if (listen(fd, 20) == -1) { 
    perror("listen error"); 
    exit(-1); 
    } 

    num_clients = 0; 
    int size = sizeof(fd); 

    while (1) { 

    int clientfd; 
    struct sockaddr_in client_addr; 
    int addrlen=sizeof(client_addr); 
    FD_ZERO(&read_set); 
    FD_SET(fd, &read_set); 

    for (i = 0; i < num_clients; i++) { //at first this part will not excute 
     FD_SET(clients[i], &read_set); 
    } 

    select(fd + num_clients + 1, &read_set, NULL, NULL, NULL); 


    if (FD_ISSET(fd, &read_set)) { 
     if ((clients[num_clients++] = accept(fd,(struct sockaddr*)&client_addr,&addrlen)) == -1) { 
     perror("accept error"); 
     continue; 
     } 
     /*printf("incoming message..................... !\n \n");*/ 
     printf("%s:%d connected\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); 
    } 


    for (i = 0; i < num_clients; i++) { 

     if (FD_ISSET(clients[i], &read_set)) { 
     msg = read(clients[i], buf, sizeof(buf)); 
     if(msg > 0){ 
      buf[msg] = 0; 
      int savedclnt = clients[i]; 
      printf("%s \n \n", buf); 

      /*for(int p=0;p<num_clients;p++) 
      { 
      if(clients[p]!= savedclnt){ 
       write(clients[p],buf,msg); 
      } 

      }*/ 
     } 

     } 

    } 
    } 
} 

と私のクライアント

int main() 
{ 

    struct uci_context *uci; 
    uci = uci_init(); 
    int sockfd; 
    int ret; 
    struct sockaddr_in dest; 
    struct addrinfo hint, *res = NULL; 
    struct hostent *host; 
    char *hostip; 
    char *string; 



    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
    { 
     puts("Unble to create socket"); 
     exit(1); 
    } 

    hostip = ucix_get_option(uci, "pack_mon", "pack_monitoring", "address"); 
    string = ucix_get_option(uci, "pack_mon", "pack_monitoring", "port"); 

    bzero(&dest, sizeof(dest)); 
    dest.sin_family = AF_INET; 
    dest.sin_port = htons(atoi(string)); 

    memset(&hint, '\0', sizeof hint); 
    hint.ai_family = PF_UNSPEC; 
    hint.ai_flags = AI_NUMERICHOST; 

    printf(" %s- %s\n", hostip, string); 



    if(isdigit(hostip[0])){ 
     ret = getaddrinfo(hostip, NULL, &hint, &res);// this is more efficient than inet_addr 

     if (ret) { 

      exit(1); 
     } 
    }else if((host = gethostbyname(hostip)) != 0){ 

     memcpy((char*)&dest.sin_addr , (char*)host->h_addr , (sizeof dest.sin_addr)+1); 

    }else{ 

     exit(1); 
     printf("cannot resolve ip address"); 
    } 


    if (connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) < 0) 
    { 

     perror("ERROR Connecting"); 
     exit(1); 
    }else{ 

     printf("Port number %s is open.....\n",string); 
    } 


    char *message; 
    message = "help"; 
    write(sockfd,message,strlen(message)); 


    close(sockfd); 
    freeaddrinfo(res); 
    return 0; 
} 

ファイアウォールルール

にsudoのiptables -I 4001 --dport TCP -p INPUTあるREFUSED示して - jアクセプト

エラー:

接続

192.168.10.155- 4001

ERROR:接続が

を拒否し、このログは、このコードから来ている:

のprintf( "%S-%sの\ n" は、次のhostIP、文字列) ;

perror( "ERROR Connecting");

exit(1);

+0

'errno'(直接的または間接的に' perror'を介して)をチェックしたい場合は、失敗した機能の直後にそれを行う必要があります。 'errno'(これは' printf'が間接的に行うかもしれない)を設定している他の関数を使うと、 'errno'の値は未定義です。 –

+0

まず、ファイアウォールが開いていますか?あなたのルールの前にこれをブロックする他のルールが存在する可能性がありますか? (おそらくあなたはiptablesの専門家ですが、確かに..を確認する)一つの方法は、そのポートとテストで別のものをセットアップすることです。それがうまくいくなら、あなたのコードに問題があると確信しています。私はファイアウォールルールを追加してからだけ起動し、問題がコード内にあるかコード内にあるかのように聞こえます。 netcatの "webserver"を設定することは、テストする一つの方法です。次のコマンドを実行します:netcat -l 5001 MrApnea

+0

あなたの問題については、 'hostip [0]'が数字の場合、あなたはoutcommentedコードで 'dest.sin_addr'を設定しません。その場合、 'hostip'がIPアドレスであると仮定すると、' getaddrinfo'を呼び出す必要はありません。 ['inet_pton'](http://man7.org/linux/man-pages/man3/inet_pton.3.html)を使用してください。また、実際には文字列ではないため、実際には 'strncpy'を使用するべきではありません。 –

答えて

0

クライアントには、接続先のIPアドレスを指定するコードがありません。それを行うことができるすべてのコードはコメントアウトされています。

更新:今、あなたのバグはここにある:

strncpy((char*)&dest.sin_addr , (char*)host->h_addr , sizeof dest.sin_addr); 

strncpy機能は、Cスタイルの文字列にのみ適しています。あなたはmemcpyかそれに類するものを使う必要があります。これは、最後のもの(ネットワークバイト順)以外のオクテットが0である場合にのみ、IPアドレスの一部をコピーします。

更新:今、あなたのバグはここにある:

printf("%d\n", connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) < 0); 
    perror("hmmmm"); 
    exit(1); 

これはprintfを呼び出して、perrorを呼び出し、その後、connectを呼び出します。問題は、printfへの呼び出しが成功してもerrnoを変更できることです。したがって、perrorへの電話では全く関係のないエラーメッセージが表示されることがあります。

+0

これは問題ではありません、私は80のような私のデバイス内の他のポートに接続することができますまたはGoogleのIPとポートにも接続できませんが、この特定のポート5001に接続できません。 –

+0

@johnleonardonwuzuruigboそれはこれは問題ではないとの観測この特定のケースでは(他のケースについては忘れてください)、OSがクライアントがどのIPアドレスに接続しようとしているかをどのように知っていると思いますか? OSにどのIPアドレスに到達しようとしているのか分からない場合、どのように動作するのでしょうか? –

+0

@johnleonardonwuzuruigboアナロジーを伝える:両方の道を見ずに通りを歩いて、車にぶつかったとします。 「私は両方の道を見ていなかったからではありません。私はリビングルームを横切る前に両方の道を見ておらず、車に当たっていませんでした。私の芝生は車に当たっていませんでした」 –

関連する問題