-1

サーバーと2つのクライアントがあります。同時にクライアントからの異なるファイルにデータを保存したいと思います。現在、2つのクライアントからの同じファイルにデータを保存しています。1つのクライアントがデータを送信した後、2番目のクライアントが送信を開始します。

2つのクライアントが同時にデータを送信するようにしたい。誰でも私を助けることができます...

server.c

void *function1(void *ptr);

typedef struct{
    int port_id;
    int thread_id;
}conn_id;

int main(int argc, char *argv[])
{
    conn_id conn_id1[2];

    conn_id1[0].port_id=7350;
    conn_id1[0].thread_id=1;
    conn_id1[1].port_id=7351;
    conn_id1[1].thread_id=2;

    conn_id* conn_ptr;


    pthread_t thread[2];
    int index=0;

    for(index=0;index<2;index++){
    conn_ptr=&conn_id1[index];

    pthread_create(&thread[index],NULL,&function1,(void*)conn_ptr);}

    pthread_join(thread[0],NULL);
    pthread_join(thread[1],NULL);

    return 0;
    }
void *function1( void *ptr)
{
    //Declaring process variables.
    int server_sockfd, client_sockfd;
    int server_len ; 
    int rc ; 

    conn_id* conn_ptr;
    conn_ptr = (conn_id*)ptr;
    unsigned client_len;
    char revbuf[LENGTH];

    struct sockaddr_in server_address;
    struct sockaddr_in client_address;


    //Remove any old socket and create an unnamed socket for the server.
    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = htons(INADDR_ANY);
    server_address.sin_port = htons(conn_ptr->port_id);
    server_len = sizeof(server_address);

    bzero(&(server_address.sin_zero), 8);
    rc = bind(server_sockfd, (struct sockaddr *) &server_address, server_len);

    printf("RC from bind = %d\n", rc ) ; 

    //Create a connection queue and wait for clients
    rc = listen(server_sockfd, 5);

    printf("RC from listen = %d\n", rc ) ; 

    client_len = sizeof(client_address);
    client_sockfd = accept(server_sockfd, (struct sockaddr *) &client_address,                &client_len);

    printf("after accept()... client = %s\n", inet_ntoa(client_address.sin_addr)) ; 

    while(1)
    {
    /*Receive File from Client */
    char* fr_name = "/home/server/Desktop/fr_client.dat";
    FILE *fr = fopen(fr_name, "a"); 

    if(fr == NULL)
        printf("File %s Cannot be opened file on server.\n", fr_name);
    else
    {
        bzero(revbuf, LENGTH); 
        int fr_block_sz = 0;
        while((fr_block_sz = recv(client_sockfd, revbuf, LENGTH, 0)) > 0) 
        {
            int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
            if(write_sz < fr_block_sz)
            {
                error("File write failed on server.\n");
            }
            bzero(revbuf, LENGTH);
            if (fr_block_sz == 0 || fr_block_sz != 512) 
            {
                break;
            }
        }
        if(fr_block_sz < 0)
        {
            if (errno == EAGAIN)
            {
                printf("recv() timed out.\n");
            }
            else
            {
                fprintf(stderr, "recv() failed due to errno = %d\n", errno);
                exit(1);
            }
        }
        printf("Ok received from client!\n");
        fclose(fr); 
    }

    /* Call the Script */
    system("cd ; chmod +x script.sh ; ./script.sh");

    /* Send File to Client */

        char* fs_name = "/home/server/Desktop/output.txt";
        char sdbuf[LENGTH]; // Send buffer
        printf("[Server] Sending %s to the Client...", fs_name);
        FILE *fs = fopen(fs_name, "r");
        if(fs == NULL)
        {
            fprintf(stderr, "ERROR: File %s not found on server. (errno =   %d)\n", fs_name, errno);
            exit(1);
        }

        bzero(sdbuf, LENGTH); 
        int fs_block_sz; 
        while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs))>0)
        {
            if(send(client_sockfd, sdbuf, fs_block_sz, 0) < 0)
            {
                fprintf(stderr, "ERROR: Failed to send file %s. (errno =  %d)\n", fs_name, errno);
                exit(1);
            }
            bzero(sdbuf, LENGTH);
        }
        printf("Ok sent to client!\n");

        close(client_sockfd);
        printf("[Server] Connection with Client closed. Server will wait  now...\n");
        while(waitpid(-1, NULL, WNOHANG) > 0);break;

}

}
4

2 に答える 2

1

もう 1 つの方法は、接続ごとにスレッドを作成し、client-ip とポートを使用してファイルに名前を付けて、スレッドごとにファイルを作成することです。後でこれらのファイルを組み合わせることができます。

于 2012-07-12T12:41:00.717 に答える
1

複数のクライアントから同時にデータを受信したい場合、基本的に次の 2 つの選択肢があります。

  1. 引き続き同期ソケット I/O を使用しますが、複数のスレッドでは、各スレッドが 1 つのクライアントと通信し、ミューテックス ロックによって保護されている共有ファイル ハンドルにデータを書き込みます。

  2. 非同期ソケット I/O、シングル スレッドを使用します。ループでは、最初に複数のソケットで select() を呼び出し、ソケットにイベントが発生したら I/O を実行する必要があります。この場合、ファイル ハンドルにミューテックスは必要ありません。

于 2012-07-12T12:36:07.807 に答える