2017-12-04 18 views
0

このプログラムは、UNIXドメインソケットを使用する単純なIPCプログラムの非ブロック通信のRTTを計算します。UNIXドメインソケットノンブロッキング操作がCのlistenで失敗しました

ソケットプログラミングで問題が発生しました。サーバ側でソケットの終了時にエラーが発生しました(listen())。ブロック のブロック版は正常に動作します。私は socket()SOCK_NONBLOCKとノンブロッキングにそれを修正しようとしたが、リスニングに失敗しているようだ:

hafizul96 @ Ubuntuの:〜/ asyntest $ ./Server [サーバプロセス]ソケット作成し、プロセスID:受け入れ7334 [サーバプロセス]ソケットのリスニング... [サーバプロセス]エラー**

クライアント:

#include <stdio.h> 
#include <stdlib.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/unistd.h> 
#include <sys/time.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <sys/un.h> 
#include <time.h> 

#define SERV_SOCK_PATH "ipc_unix_sock.server" 
#define CLIN_SOCK_PATH "ipc_unix_sock.client" 

void Array_Init(int *, int); 
void Write_to_File(FILE *, int *, int); 

int main(int argc, char *argv[]) 
{ 
    struct sockaddr_un serv_addr, cli_addr; 
    int client_socket, add_len, rc, array_len, send_bytes, recv_bytes; 
    pid_t process_id = getpid(); 
    clock_t start, end; 
    double elapsed = 0.0; 
    FILE *cli_arr_recv; 
    FILE *cli_arr_send; 
    char arr_len[10]; 
    int *Array_Buff; 
    array_len = atoi(argv[1]); 
    sprintf(arr_len, "%d", array_len); 


    Array_Buff = malloc(sizeof(int)*array_len); 
    cli_arr_send = fopen("cli_arr_send.txt","w+"); 
    cli_arr_recv = fopen("cli_arr_recv.txt","w+"); 

    memset(&serv_addr, 0, sizeof(struct sockaddr_un)); 
    memset(&cli_addr, 0, sizeof(struct sockaddr_un)); 
    memset(Array_Buff, 0, array_len); 
    Array_Init(Array_Buff, array_len); 
    //Copy arrays to file 
    Write_to_File(cli_arr_send, Array_Buff, array_len); 

//NON-BLOCKING SOCKET// 
    if((client_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0))<0) 
    { 
     printf("[CLIENT PROCESS] Socket Creation Error\n"); 
     fclose(cli_arr_recv); 
     fclose(cli_arr_send); 
     close(client_socket); 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     printf("[CLIENT PROCESS] Socket Created, Process ID :%d\n", process_id); 
     printf("[CLIENT PROCESS] %lubytes Allocated\n", sizeof(int)*array_len); 
    } 

    cli_addr.sun_family = AF_UNIX; 
    strcpy(cli_addr.sun_path, CLIN_SOCK_PATH); 
    add_len = sizeof(cli_addr); 

    unlink(CLIN_SOCK_PATH); 
    if((rc = bind(client_socket, (struct sockaddr*)&cli_addr, add_len))<0) 
    { 
     printf("[CLIENT PROCESS] Bind error \n"); 
     fclose(cli_arr_recv); 
     fclose(cli_arr_send); 
     close(client_socket); 
     exit(EXIT_FAILURE); 
    } 

    serv_addr.sun_family = AF_UNIX; 
    strcpy(serv_addr.sun_path, SERV_SOCK_PATH); 
    if((rc = connect(client_socket, (struct sockaddr*)&serv_addr, add_len))<0) 
    { 
     printf("[CLIENT PROCESS] Failed to Connect to Server Process\n"); 
     fclose(cli_arr_recv); 
     fclose(cli_arr_send); 
     close(client_socket); 
     exit(EXIT_FAILURE); 
    } 


    start = clock(); 
    if((rc = send(client_socket, arr_len, sizeof(arr_len), 0))<0) 
    { 
     printf("[CLIENT PROCESS] Failed to Send Array Len to Server Process"); 
     fclose(cli_arr_recv); 
     fclose(cli_arr_send); 
     close(client_socket); 
     exit(EXIT_FAILURE); 
    } 

    if((send_bytes = send(client_socket, Array_Buff, sizeof(int)*array_len, 0))<0) 
    { 
     printf("[CLIENT PROCESS] Failed to Send Array Elements to Server Process"); 
     fclose(cli_arr_recv); 
     fclose(cli_arr_send); 
     close(client_socket); 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     printf("[CLIENT PROCESS] Total Bytes Sent = %dbytes\n",send_bytes); 
     memset(Array_Buff, 0, array_len); //reset buffer 
     if((recv_bytes = recv(client_socket, Array_Buff, sizeof(int)*array_len, MSG_WAITALL))<0) 
     { 
      fclose(cli_arr_recv); 
      fclose(cli_arr_send); 
      close(client_socket); 
      exit(EXIT_FAILURE); 
     } 
     else 
     { 
      //Finishes RTT 
      end = clock(); 
      printf("[CLIENT PROCESS] Total Bytes Received Back = %dbytes\n",recv_bytes); 
      Write_to_File(cli_arr_recv, Array_Buff, array_len); 
     } 

    } 
    elapsed = (end - start)/(double)CLOCKS_PER_SEC; 
    printf("[CLIENT PROCESS] RTT(Round Trip Time) is = %fs\n", elapsed); 
    printf("[CLIENT PROCESS] Program Completed.\n"); 

    free(Array_Buff); 
    fclose(cli_arr_recv); 
    fclose(cli_arr_send); 
    close(client_socket); 
    exit(EXIT_SUCCESS); 
} 
void Array_Init(int *Array_Buff, int array_len) 
{ 
    unsigned int seed = 184611; 
    srand(seed); 
    for(int i = 0; i< array_len; i++) 
    { 
     *(Array_Buff++) = rand() % 999999; 
    } 
} 
void Write_to_File(FILE *outfile, int *Array_Buff, int array_len) 
{ 
    for(int i = 0; i<array_len; i++) 
    { 
     fprintf(outfile, " %d ", *(Array_Buff++)); 
    } 
    printf("[CLIENT PROCESS] File Write Completed.. \n"); 
} 

サーバー:

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

#define SERV_SOCK_PATH "ipc_unix_sock.server" 

void Write_to_File(FILE *, int *, int); 

int main(int argc, char *argv[]) 
{ 
    struct sockaddr_un serv_addr, cli_addr; 
    int server_sock, client_sock, add_len, rc, array_len; 
    int backlog = 2, recv_bytes = 0, send_bytes = 0; 
    pid_t process_id = getpid(); 
    FILE *serv_file; 
    int *Array_Buff; 
    char arr_len[10]; 

    serv_file = fopen("serv_recv_arr.txt","w+"); 

    /*Making sure that address struct set to zero*/ 
    memset(&serv_addr, 0, sizeof(struct sockaddr_un)); 
    memset(&cli_addr, 0, sizeof(struct sockaddr_un)); 
    memset(arr_len, 0, 10); 
//NON-BLOCKING SOCKET TYPE 
    if((server_sock = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) < 0) 
    { 
     printf("[SERVER PROCESS] Error Socket\n"); 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     printf("[SERVER PROCESS] Socket Created, Process ID : %d\n", process_id); 
    } 

    serv_addr.sun_family = AF_UNIX; 
    strcpy(serv_addr.sun_path, SERV_SOCK_PATH); 
    add_len = sizeof(serv_addr); 

    unlink(SERV_SOCK_PATH); 
    if((rc = bind(server_sock, (struct sockaddr*)&serv_addr, add_len))<0) 
    { 
    printf("[SERVER PROCESS] Error Binding\n"); 
    close(server_sock); 
    exit(EXIT_FAILURE); 
    } 

    if((rc = listen(server_sock, backlog)) <0) 
    { 
     printf("[SERVER PROCESS] Error Listening\n"); 
     close(server_sock); 
     fclose(serv_file); 
     exit(EXIT_FAILURE); 
    } 

    printf("[SERVER PROCESS] Socket Listening..\n"); 

    if((client_sock = accept(server_sock, (struct sockaddr*)&client_sock, &add_len))<0) 
    { 
     printf("[SERVER PROCESS] Error Accepting\n"); 
     close(server_sock); 
     close(client_sock); 
     fclose(serv_file); 
     exit(EXIT_FAILURE); 
    } 

    add_len = sizeof(cli_addr); 
    if((rc = getpeername(client_sock, (struct sockaddr*)&cli_addr, &add_len))<0) 
    { 
     printf("[SERVER PROCESS] Error Getting Peername\n"); 
     close(server_sock); 
     close(client_sock); 
     fclose(serv_file); 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     printf("[SERVER PROCESS] Client Socket Filepath = %s\n", cli_addr.sun_path); 
    } 

    printf("[SERVER PROCESS] Waiting to Recv Msg..\n"); 


    if((rc = recv(client_sock, arr_len, sizeof(arr_len), MSG_WAITALL))<0) 
    { 
     printf("[SERVER PROCESS] Error Receiving Msg..\n"); 
     close(server_sock); 
     close(client_sock); 
     fclose(serv_file); 
     exit(EXIT_FAILURE); 
    } 
    printf("[SERVER PROCESS] Array Len Received %s\n", arr_len); 
    array_len = atoi(arr_len); 
    Array_Buff = malloc(sizeof(int)*array_len); 
    printf("[SERVER PROCESS] %lubytes Allocated\n", sizeof(int)*array_len); 
    memset(Array_Buff, 0, array_len); 

    if((recv_bytes = recv(client_sock, Array_Buff, sizeof(int)*array_len, MSG_WAITALL))<0) 
    { 
     printf("[SERVER PROCESS] Error Receiving Msg..\n"); 
     close(server_sock); 
     close(client_sock); 
     fclose(serv_file); 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     printf("[SERVER PROCESS] Total Bytes Recv = %dbytes\n",recv_bytes); 
     if((send_bytes = send(client_sock, Array_Buff, sizeof(int)*array_len, 0))<0) 
     { 
      printf("[SERVER PROCESS] Error Sending Back Array\n"); 
      close(server_sock); 
      close(client_sock); 
      fclose(serv_file); 
      exit(EXIT_FAILURE); 
     } 
     else 
     { 
      printf("[SERVER PROCESS] Total Bytes Sent Back = %dbytes\n", send_bytes); 
     } 

    } 
    Write_to_File(serv_file, Array_Buff, array_len); 
    printf("[SERVER PROCESS] Program Completed.\n"); 

    free(Array_Buff); 
    close(server_sock); 
    close(client_sock); 
    exit(EXIT_SUCCESS); 
} 

void Write_to_File(FILE *outfile, int *Array_Buff, int array_len) 
{ 
    for(int i = 0; i<array_len; i++) 
    { 
     fprintf(outfile, " %d ", *(Array_Buff++)); 
    } 
    printf("[SERVER PROCESS] File Write Completed.. \n"); 
    fclose(outfile); 
} 

問題が何であり、どのように修正するのかは誰にも分かりますか?

+0

エラーが発生した場所は正確にわかります。エラー値を確認し、何が起こったのかを見てください。 –

+0

メッセージが 'accept()'であることが明確に示されたときに、エラーが 'listen()'にあるのはなぜですか?ブロックされている間何もしていないときに、非ブロックIOを使用しているのはなぜですか? – pat

+0

コードを編集して問題の[mcve]に減らしてください。あなたの現在のコードには、問題の周辺にあるものが多く含まれています。通常、最小単位のサンプルは良い単位テストと似ています。 –

答えて

1

ソケットが非ブロックであるため、acceptは接続が発生するまで待機しませんが、EAGAINまたはEWOULDBLOCKの値を返します。別の値を返すまで、acceptを繰り返し呼び出す必要があります。これらの呼び出しでCPUを100%消費するのを避けるには、2つの呼び出しの間にsleepを実行するか、selectまたはpollを使用して、ソケットが読み取り可能になるまで待ちます。

関連する問題