2

I created a C server and a java client. I was sending a command like ls through the client and server should execute it. However read in c server is still waiting for input. how to solve this problem.

Java client

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;


class HelloWorld
{
    public static void main(String... abc) {

    try
    {
        BufferedReader br = new BufferedReader(new       InputStreamReader(System.in));
       System.out.println("Enter ip and port : ");
       String ip ;
       String p;
       String ss;
       int port;

       ip = br.readLine();
       p = br.readLine();
       port = Integer.parseInt(p);
       Socket s = new Socket(ip,port);
       OutputStream os = s.getOutputStream();
       PrintWriter pw = new PrintWriter(os);

       Scanner in = new Scanner(System.in);
       ss = in.nextLine();      
       pw.print(s);
       pw.flush();
       pw.close();
    }
    catch(Exception e){
        System.out.println("ERROR!!!");}
   }
}

here is the c server.

#include"Headers.h"

void comm(char * s_port)
{
    int sockfd, newsockfd, portno;
    socklen_t clilen;
    char buffer[MAXBUFFER];
    char newbuffer[MAXBUFFER];
    char var[MAXBUFFER] = " > file.txt";
    int n;

    struct sockaddr_in serv_addr, cli_addr;

    FILE *fp = NULL;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    if (sockfd < 0) 
     error("ERROR opening socket");

    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(s_port);

    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) 
          error("ERROR on binding");

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

    if (newsockfd < 0) 
          error("ERROR on accept");
    while (1)
    {   
        bzero(buffer,1024);
        n = read(newsockfd,buffer,1024);

        if (strcmp(buffer , "exit\n") == 0)
         break;

       if (n < 0) error("ERROR reading from socket");
       printf("Here is the message: %s\n",buffer);
       strcpy(newbuffer,"");
       if (buffer[strlen(buffer) - 1] == '\n')
          buffer[strlen(buffer) - 1] = '\0';

       strcat(newbuffer, buffer);
       strcat(newbuffer, var);
       printf("%s",newbuffer);
       system(newbuffer);
        break;

    if (n < 0) error("writing to socket");
 }  
     close(newsockfd);
     close(sockfd);
}
Tejas
  • 97
  • 8

3 Answers3

3
    n = read(newsockfd,buffer,1024);

    if (strcmp(buffer , "exit\n") == 0)
     break;

You forgot to implement a protocol. You can't just read an arbitrary bunch of bytes from the connection and then treat it as a message. TCP has no conception of a message. If you want to send and receive messages, you have to define what you mean by a "message" and write code to send and receive that implements that definition.

There are probably other problems with your code, but this defect is so severe and so fundamental, you really need to fix it first.

If your definition of a message is "a sequence of ASCII characters not including a zero byte or a newline terminated by a newline", then you need to write code to receive such a sequence. You can't just call read and expect it to find the message boundaries since it has no idea that you use newline as a message boundary.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
1

The main problem with your code is the way you handle strings in C.

Your server seems to assume that you are sending UTF-8 encoded strings over the network but strings in Java are encoded in UTF-16 by default. You will also need a way to ensure that each message buffer only contains valid Unicode characters. Each character in a Unicode string can use multiple bytes and you might get partial sent characters on the server side.

Johan Mattsson
  • 305
  • 6
  • 19
0

You have a small typo in the java program:

   pw.print(s);

s is the socket, so you are sending s.toString(). I think you mean:

   pw.print(ss);

Also, you need to decide on a message protocol, just as @DavidSchwartz points out.

Some useful links:

Protocol types

Understanding and designing socket message protocols

Community
  • 1
  • 1
Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82