tags:

views:

117

answers:

3

Dear All,

I am pasting my code for a simple socket server in C and a java client.

I use write method sending character by character in Java. However after the chunk of characters are sent(here, 'h', 'e', 'y') , the Java client is send blocked as the C server does not reply to it :(

I am assuming there is some problem with sending a null character(from the Java write) that would stop the recv at the C side.

Any help would be greatly appreciated.

     //C server:



#include <stdio.h>   /* standard in and output*/
#include <sys/socket.h> /* for socket() and socket functions*/
#include <arpa/inet.h>  /* for sockaddr_in and inet_ntoa() */
#include <stdlib.h>    
#include <string.h>     
#include <unistd.h>     /* for close() */


int main(int argc, char *argv[]){
 int sock, connected, bytes_received, true = 1;  
    char recv_data;      
 char replyBuffer[32];

    struct sockaddr_in server_addr,client_addr;    
    int sin_size;       
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("Socket");
        exit(1);
    }

    if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) == -1) {
        perror("Setsockopt");
        exit(1);
    }

    server_addr.sin_family = AF_INET;         
    server_addr.sin_port = htons(2400);     
    server_addr.sin_addr.s_addr = INADDR_ANY; 
    bzero(&(server_addr.sin_zero),8); 

    if (bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
        perror("Unable to bind");
            exit(1);
    }

    if (listen(sock, 5) == -1) {
        perror("Listen");
        exit(1);
    }

 printf("\nTCPServer Waiting for client on port 2400");

   while(1){  
        sin_size = sizeof(client_addr);
        connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size);
        printf("\n Got a connection from (%s , %d)",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));


       while ((bytes_received = recv(connected,&recv_data,1,0)) > 0){
  printf("\nrecv= %c\n", recv_data);
  }
  int success = 1;
  sprintf(replyBuffer, "%d", success); 
  printf("reply buffer = %s\n", replyBuffer);
  if (send(connected, replyBuffer, strlen(replyBuffer), 0) == -1)
    perror("send() failed"); 
    success = 0;
  close(connected);
 }
}

Java Client:

import java.net.; import java.io.;

public class Client1
{
 public static void main(String[] args) throws IOException {
  if (args.length < 2) {
   System.err.println("Usage: java Client1 <IP address> <Port number>");
   System.exit(0);
  }
  BufferedReader in = null;
  OutputStream out = null;
  Socket sock = null;

  try {
   sock = new Socket(args[0], Integer.parseInt(args[1]));
   out = sock.getOutputStream();
   in = new BufferedReader(new InputStreamReader(sock.getInputStream()));

    String line = "hey";
    String responseline = null;
char[] strArray;
strArray = line.toCharArray();

while (true) {
for( int index = 0; index < strArray.length; index++){
 out.write(strArray[index]);
}
out.flush();
System.out.println("data sent " );
System.out.println("val returned"+in.readLine());
   }
  }
  catch (IOException ioe) {
   System.err.println(ioe);
  }
  finally {
   if (in != null)
    in.close();

   if (out != null)
    out.close();
   if (sock != null)
    sock.close();
  }
 }
}
+3  A: 

from javadoc for BufferedReader.readLine()

Read a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed. 

That's why it blocks (no lf, no cr, no crlf)

[edit]
You need to create an EOL indicator that the C program understands (just like readLine() in the java client. Let that indicator be '\n' (for consistency if nothing else)
In Client.java, append '\n' to your sent string.
In tst.c, test for '\n', when it's received, break from the recv() loop
[/edit]

KevinDTimm
But I tried sending '/n', '/0', '/r' and none of these worked...finally I even tried passing just 'null' and then the Server responded , however immediately, my java client stopped understandably after a null point exception.
Thank you Kevin, I did exactly that and now the C code proceeds further and after it receives the entire character set, it sends back a value(here success = 1 in replyBuffer) however this time the in.readLine() in java blocks! But doesnt it recognise null character? I even put the in.readLine() in a while loop till it is not equal to null... but it blocks... :( :(
communcations in both directions must be '\n' terminated (that is your EOL indicator on both side) -- sprintf(replyBuffer, "%d\n", success);
KevinDTimm
U saved my day :) it works now
don't forget to 'accept' :)
KevinDTimm
+1  A: 

Your assumption of the problem is correct. The recv call will always return a value greater than zero. I suggest using a special character to designate the end of the text and terminating the recv() loop when that character is read.

Steve Emmerson
But I tried sending '/n', '/0', '/r' and none of these worked...finally I even tried passing just 'null' and then the Server responded , however immediately, my java client stopped understandably after a null point exception.
Steve, can you suggest what special character to pass? Btw I will use this program to pass ASCII files(text) ...any suggestions?
@Steve - once the EOL terminator is defined, sent and identified, this all works very nicely :)
KevinDTimm
@user489152 The code you posted doesn't check the received character: it only prints it. Modify the code to check the character against the termination character.
Steve Emmerson