adrian2012
adrian2012

Reputation: 17

Strange behavior in TCP transmission

My server-client application consists of the following modules:

client (written in Java) connects to server and sends a file;

server (written in C) receives the file and sends a char array message.

The problem is that after receiving the file, the server is unable to send the message or the client is unable to receive it.

Here is my code for server application:

int main(int argc , char *argv[])
{
    WSADATA wsa;
    SOCKET s , new_socket;
    struct sockaddr_in server , client;
    int c, bytecount, nr_transf, rest_byte, i, bytesRead;
    int recv_size, file_size;
    char message[1000];     
    char buffer[1000];
    int buffer_len = 1000;
    FILE *f = fopen("out.jpg", "wb");

    printf("\nInitialising Winsock...");
    if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
    {
        printf("Failed. Error Code : %d", WSAGetLastError());
        return 1;
    }

    printf("Initialised.\n");

    //Create a socket
    if((s = socket(AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET)
    {
        printf("Could not create socket : %d" , WSAGetLastError());
        getch();
        return 0;
    }

    printf("Socket created.\n");

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(8888);

    //Bind
    if(bind(s, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
    {
        printf("Bind failed with error code : %d" , WSAGetLastError());
        getch();
        return 0;
    }

    puts("Bind done");

    //Listen to incoming connections
    listen(s, 3);

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

    c = sizeof(struct sockaddr_in);
    new_socket = accept(s, (struct sockaddr*)&client, &c);
    if (new_socket == INVALID_SOCKET)
  {
        printf("accept failed with error code : %d", WSAGetLastError());
        getch();
        return 0;
    }

    printf("Connection accepted");

    //Receive image
    while((bytesRead = recv(new_socket, buffer, buffer_len, 0)) > 0)
    {
        fwrite(buffer, 1, bytesRead, f);
    }

    fclose(f);
    printf("\nReceive finished!");


    //Send messsage
    char my_message[100];
    strcpy(my_message, "Hello World!");

    send(new_socket, my_message, strlen(my_message), 0);

    closesocket(s);
    WSACleanup();

    getch();
    return 0;
}

And the code for client application:

public class MyClass
{
    public static void main(String[] args) 
    {
        String fileName = "1.jpg", receiveMessage;
        File a_file = new File(fileName);  
        int j;
        OutputStream output = null;
        InputStream input = null;
        ObjectInputStream in = null;
        Socket socket = null;

        try  
        {           
            // Create a socket
            socket = new Socket("192.168.0.122", 8888);

            FileInputStream fileInputStream = new FileInputStream(fileName);
            byte[] buffer = new byte[1000];
            int bytesRead = 0;
            output = socket.getOutputStream();     
            input = socket.getInputStream();     

            while((bytesRead = fileInputStream.read(buffer))>0)
            {
                output.write(buffer,0,bytesRead);
            }

            fileInputStream.close();        
            System.out.println("Send finished!");

            input.read(buffer);
            System.out.println("Receive finished!");
        }  
        catch(Exception e)  
        {  
            e.printStackTrace();  
        } 
        finally
        {
            try
            {
                in.close();
                output.close();
                socket.close();
            }
            catch(Exception e)
            {

            }
        }
    }
}

Any ideas to solve this problem? Thanks in advance!

Upvotes: 0

Views: 150

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409146

It's because you have blocking sockets. When a socket is created (by connecting or by accepting) it is in blocking mode. This means that if there is no data to receive it will not return, effectively blocking the caller.

So after you received the last byte in the loop in the server, the recv call will block indefinitely.

On Windows with winsockets, you use the ioctlsocket function to make a socket blocking or non-blocking. The linked reference have an example which shows hot to make a socket blocking or non-blocking.

Upvotes: 3

Related Questions