Unable to print message from server side to client side before sending any message from client

半城伤御伤魂 提交于 2020-01-06 03:48:08

问题


I have two programs for server and client. My server can connect to multiple client. But the problem right now I am facing is that, I want to display some message from the server side to client side but I am unable to do that. Both the server and client program are provided below. I think the syntax that is preventing me to print the message on the client side is scanfwhich is used the code of client (second line of the while loop). I am not getting any solution for that about how to display the two messages from the server side when the client will get connected.

Problem 1: Server side messages that I want to display on the client side when client gets connected : (can be found in the new_connection_handler function)

 message = "This is connection handler\n";
 message = "Type something \n";

Problem 2:

Why I need to use the sleep (2) on the client side? If I do not use the sleep (2), then I cannot receive the data sent by the client on the client side. The data shows when I send something second time from the client side.

Problem 3:

Is it possible to write both the client and server code together and compile and run it using command line arguments?

Server Code:

#include<stdio.h>
#include<string.h>    //strlen
#include<stdlib.h>    //strlen
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr
#include<unistd.h>    //write
#include<pthread.h> //for thread


 #define MAX_CLIENTS 5


//the thread function
void *new_connection_handler(void *);

int main(int argc , char *argv[])
{
    int socket_desc , client_sock , c , *new_sock;
    struct sockaddr_in server , client;


    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }


    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 8888 );
    bzero (&server.sin_zero, 8);



    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
        //print the error message
        perror("bind failed. Error");
        return 1;
    }


    //Listen
    listen(socket_desc , MAX_CLIENTS);



    //Accept and incoming connection
    printf("Waiting for incoming connections\n");




    c = sizeof(struct sockaddr_in);
    while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) )
    {
        printf("Connection accepted");



        pthread_t thread_id;




        if( pthread_create( &thread_id , NULL ,  new_connection_handler , (void*) &client_sock) < 0)
        {
            perror("could not create thread");
            return 1;
        }



     printf("Handler assigned\n");
    }


    if (client_sock < 0)
    {
        perror("accept failed");
        return 1;
    }

    return 0;
}


void *new_connection_handler(void *socket_desc)
{
    //Get the socket descriptor
    int sock = *(int*)socket_desc;
    int read_size;
    char *message , client_message[2000];



    //Send some messages to the client
    message = "This is connection handler\n";
    write(sock , message , strlen(message));


    message = "Type something \n";
    write(sock , message , strlen(message));


    //Receive a message from client
    while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
    {
        //Send the message back to client
        write(sock , client_message , strlen(client_message));
    }



    if(read_size == 0)
    {
        printf("Client disconnected\n");
        fflush(stdout);
    }
    else if(read_size == -1)
    {
        perror("recv failed");
    }

    //Free the socket pointer
    free(socket_desc);

    return 0;
}

Client Code:

#include<stdio.h> //printf
#include<string.h>    //strlen
#include<sys/socket.h>    //socket
#include<arpa/inet.h> //inet_addr

int main(int argc , char *argv[])
{
    int sock;
    struct sockaddr_in server;
    char message[1000] , server_reply[2000];
    int len;

    //Create socket
    sock = socket(AF_INET , SOCK_STREAM , 0);
    if (sock == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons( 8888 );

    //Connect to remote server
    if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
    {
        perror("connect failed. Error");
        return 1;
    }

    puts("Connected\n");

    //keep communicating with server
    while(1)
    {
        printf("Enter message : ");
        scanf("%s" , message);


        //Send some data
        if( send(sock , message , strlen(message) , 0) < 0)
        {
            puts("Send failed");
            return 1;
        }
        sleep (2);
        //Receive a reply from the server
        if((len = recv(sock , server_reply , 2000 , 0)) < 0)
        {
            puts("recv failed");
            break;
        }

        puts("Server reply :");
        server_reply [len]='\0';
    printf("%s\n", server_reply);


    }

    close(sock);

    return 0;
}

回答1:


Your frames are out of sync You open your client handling thread with two sends from the server. Without your "sleep", you pick up one, but not the other. your buffer sizes are also not being used correctly, as they're inconsistently being treated as terminated strings when in fact their send length is based on strlen (which is ok, so long as it is consistent).

I think this is what you're trying to do, with a few modifications:

Client Code

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdint.h>

int main(int argc , char *argv[])
{
    int sock;
    struct sockaddr_in server;
    char message[1000] , server_reply[2000];
    int len;

    //Create socket
    sock = socket(AF_INET , SOCK_STREAM , 0);
    if (sock == -1)
    {
        printf("Could not create socket");
    }
    puts("Socket created");

    server.sin_addr.s_addr = inet_addr("127.0.0.1");
    server.sin_family = AF_INET;
    server.sin_port = htons( 8888 );

    //Connect to remote server
    if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
    {
        perror("connect failed. Error");
        return 1;
    }

    puts("Connected\n");

    //keep communicating with server
    while((len = recv(sock, server_reply, sizeof(server_reply), 0)) > 0)
    {
        printf("Server reply: %.*s", len, server_reply);

        printf("Enter message : ");
        if (fgets(message, sizeof(message), stdin) == NULL)
            break;

        //Send some data
        if( send(sock , message , strlen(message) , 0) < 0)
        {
            puts("Send failed");
            return 1;
        }
    }

    close(sock);

    return 0;
}

Server Code

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<pthread.h>
#include<stdint.h>


#define MAX_CLIENTS 5


//the thread function
void *new_connection_handler(void *);

int main(int argc , char *argv[])
{
    int socket_desc , client_sock;
    struct sockaddr_in server , client;
    socklen_t c = sizeof(client);

    //Create socket
    socket_desc = socket(AF_INET , SOCK_STREAM , 0);
    if (socket_desc == -1)
    {
        printf("Could not create socket");
    }

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 8888 );
    bzero (&server.sin_zero, 8);

    //Bind
    if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
    {
        //print the error message
        perror("bind failed. Error");
        return 1;
    }

    //Listen
    listen(socket_desc , MAX_CLIENTS);

    //Accept and incoming connection
    printf("Waiting for incoming connections\n");

    c = sizeof(client);
    while( (client_sock = accept(socket_desc, (struct sockaddr *)&client, &c)) )
    {
        printf("Connection accepted");
        pthread_t thread_id;

        if( pthread_create( &thread_id , NULL ,  new_connection_handler , (void*) (intptr_t)client_sock) < 0)
        {
            perror("could not create thread");
            return 1;
        }

        printf("Handler assigned\n");
    }


    if (client_sock < 0)
    {
        perror("accept failed");
        return 1;
    }

    return 0;
}


void *new_connection_handler(void *socket_desc)
{
    //Get the socket descriptor
    int sock = (intptr_t)socket_desc;
    int read_size = 0;
    char client_message[2000];

    static const char rdy[] = "READY\n";
    write(sock, rdy, sizeof(rdy)-1);

    //Receive a message from client
    while( (read_size = recv(sock , client_message , sizeof(client_message) , 0)) > 0 )
        write(sock , client_message , read_size);

    if(read_size == 0)
    {
        printf("Client disconnected\n");
        fflush(stdout);
    }
    else if(read_size == -1)
    {
        perror("recv failed");
    }

    return 0;
}

This still needs better join-logic on the client threads, but if you paste and compile each with appropriate flags I think it does what you're trying to achieve.

Best of luck.



来源:https://stackoverflow.com/questions/24648709/unable-to-print-message-from-server-side-to-client-side-before-sending-any-messa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!