Я создал C-сервер и Java-клиент. Я отправлял команду типа ls через клиента, и сервер должен ее выполнить. Однако прочитанный в c сервер все еще ожидает ввода. Как решить эту проблему.

Java-клиент

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!!!");}
   }
}

Вот c-сервер.

#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);
}
2
Tejas 7 Янв 2016 в 12:41

3 ответа

Лучший ответ
    n = read(newsockfd,buffer,1024);

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

Вы забыли реализовать протокол. Вы не можете просто прочитать произвольную группу байтов из соединения и затем обработать ее как сообщение. TCP не имеет понятия о сообщении. Если вы хотите отправлять и получать сообщения, вы должны определить, что вы подразумеваете под «сообщением», и написать код для отправки и получения, который реализует это определение.

Вероятно, с вашим кодом есть другие проблемы, но этот дефект настолько серьезен и настолько фундаментален, что вам действительно нужно сначала исправить его.

Если ваше определение сообщения - «последовательность символов ASCII, не включающая нулевой байт или новую строку, заканчивающуюся новой строкой», то вам нужно написать код для получения такой последовательности. Вы не можете просто вызвать read и ожидать, что он найдет границы сообщения, поскольку он не знает, что вы используете новую строку в качестве границы сообщения.

3
David Schwartz 7 Янв 2016 в 10:16

У вас есть небольшая опечатка в java-программе:

   pw.print(s);

s - это сокет, поэтому вы отправляете s.toString(). Я думаю, вы имеете в виду:

   pw.print(ss);

Кроме того, вам необходимо выбрать протокол сообщений, как указывает @DavidSchwartz.

Некоторые полезные ссылки:

Типы протоколов

Понимание и проектирование протоколов сообщений сокетов

0
Community 23 Май 2017 в 12:31

Основная проблема с вашим кодом - это способ обработки строк в C.

Кажется, ваш сервер предполагает, что вы отправляете закодированные строки UTF-8 по сети, но строки в Java по умолчанию закодированы в UTF-16. Вам также понадобится способ гарантировать, что каждый буфер сообщений содержит только допустимые символы Unicode. Каждый символ в строке Unicode может использовать несколько байтов, и вы можете получить частично отправленные символы на стороне сервера.

1
Johan 7 Янв 2016 в 10:07