views:

70

answers:

2

Hey all,

I am working on client server architecture and i am just beginner in this thing. Here my server is of C and client is of Java and i want to send a binary/database (.db)/image file of size around 10 - 20 MB from C server to the Java client. But data is lost while implementing the following code:

Server side C code is:

int sockfd, newsockfd, portno, clilen;   

struct sockaddr_in serv_addr, client_addr;

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0)
{
    strcpy(message,"Error opening socket");
    eFlag = 1;
    send_message(message);
}

bzero((char *)&serv_addr, sizeof(serv_addr));
portno = 6789;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);

if(bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
{
    strcpy(message,"Error on binding");
    eFlag = 1;
    send_message(message);
}

listen(sockfd, 5);
clilen = sizeof(client_addr);
newsockfd = accept(sockfd, (struct sockaddr *)&client_addr, &clilen);

if(newsockfd < 0)
{
    strcpy(message,"Error on accept");
    eFlag = 1;
    send_message();
    exit(4);
}

void send_file()
{
    buffer = (char *)malloc(sizeof(char)*lSize);

    result = fread(buffer, sizeof(char), lSize, fp);
    printf("\n\n########## data read into buffer successfully #######");


    if(newsockfd)
    {
        n = send(newsockfd, buffer, lSize);
        printf("\n\n$$$$$$$$ Data sent successfully $$$$$");
        strcpy(message,"Data sent successfully");
        send_message(message);
    }


    else
    {
        strcpy(message, "Error writing on socket");
        send_message(message);
    }

    sleep(sleepTime);
    sleepTime = (int) (sleepTime*1.02);

    free(buffer);
}

And, my client side Java code is:

                    final int PORT_NO = 6789;
        final String Server_name = "192.133.133.1";
        Socket m_socket = null;
        String str;
        int ch;

    try {
        if(m_socket == null)
            m_socket = new Socket(Server_name, PORT_NO);
        if(m_socket == null)
            System.out.println("Unable to open the socket");


    DataInputStream dis = new DataInputStream(m_socket.getInputStream());
    PrintStream ps = new PrintStream(m_socket.getOutputStream());

    DataInputStream ds = new DataInputStream(System.in);

    while(true)
    {
        System.out.println("1. Synchronize");
        System.out.println("2. Exit");
        System.out.println("Enter your choice...");
        str = ds.readLine();
        ch = Integer.parseInt(str);

        switch(ch)
        {
        case 1:
     ps.println("<message action='buttonpress' value='synchronize' />");
     System.out.println("avilable data to read is:"+dis.available());
     FileOutputStream fos = new FileOutputStream("mukul.db");



            byte data[] = new byte[102400]; //100 Kb byte array

                            dis.read(data);


            String str_data = new String(data);
            str_data = str_data.trim();
            data = str_data.getBytes();

            fos.write(data);
            fos.close();

            break;

here only part of data is read i.e around 10 kb or less.

I am just a beginner to such posts and my code may be cumbersome, so please ignore all the mistakes in posting.

So please kindly tell me how can i receive 1 MB/10 MB of data in this client-server architecture without the loss of data.

What if i use "sendfile(out_fp, in_fp, pos, len)" method in C code instead of "send()". This method sends file handle. So what will be the corresponding function in Java to capture file handle.

Thank you in advance.

A: 
  1. m_socket can't possibly be null the line after you call m_socket = new Socket(...). It will either throw an exception or assign a Socket to m_socket, never null. So that test is pointless.

  2. After you call readLine() you must check for a null return value, which means EOS, which means the other end has closed the connection, which means you must exit the reading loop and close the socket.

  3. As it says in the Javadoc, InputStream.available() shouldn't be used for a test for EOS. Its contract is to return the number of bytes that can be read without blocking. That's rarely the same as the length of an incoming file via a socket. You must keep reading the socket until EOS:

    int count; byte[] buffer = new byte[8192]; while ((count = in.read(buffer)) > 0) out.write(buffer, 0, count);

If your sending end doesn't close the socket when it finishes sending the file you will have to have it send the file length ahead of the file, and modify the loop above to read exactly that many bytes.

EJP
Thank you, it helped me in sending the data from server successfully.
+1  A: 

You're misusing the send()/recv() functions. send() and recv() are not required to send as much data as you request, due to limits that may be present in the kernel. You have to call send() over and over until all data has been pushed through.

e.g.:

int sent = 0;
int rc;
while ( sent < should_send )
{
   rc = send(sock, buffer + sent, should_send - sent, 0);
   if ( rc <= 0 ) // Error or hangup
      // do some error handling;

   sent += rc;
}
Maister
Thank you. it helped in receiving data successfully on client.