Java套接字客户端可以';无法从C服务器接收响应

Java套接字客户端可以';无法从C服务器接收响应,java,c,sockets,Java,C,Sockets,我想用java连接到c套接字服务器,发送linux命令,该命令将在服务器上执行,并在java客户端接收结果 我有一个C语言的socket客户端,如下所示: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include &

我想用java连接到c套接字服务器,发送linux命令,该命令将在服务器上执行,并在java客户端接收结果

我有一个C语言的socket客户端,如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/wait.h>
#include <pthread.h>

#define MAXCON 500 
#define BUFFSIZE 256
#define MAXCOMMAND 500

void *newClient(void *argSocket);

int main (int argc, char *argv[]) {

    fflush(stdout);
    struct sockaddr_in addrIn;
    struct sockaddr_in clientAddr;
    int mainSocket = socket(PF_INET, SOCK_STREAM, 0);

    memset(&addrIn, '\0', sizeof(addrIn));
    addrIn.sin_family = AF_INET;
    addrIn.sin_addr.s_addr = INADDR_ANY;
    addrIn.sin_port = htons(6666);

    if(setsockopt(mainSocket, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int))<0){
        perror("SETSOCKOPT ERROR");
        exit(-1);
    }

    if(bind(mainSocket, (struct sockaddr *)&addrIn, sizeof(addrIn))<0){
        perror("PORT IS ALREADY IN USE");
        exit(-1);
    }

    listen(mainSocket, MAXCON); 

    while(1){
        int newSocket;
        int clientAddrLength = sizeof(clientAddr);

        if((newSocket = accept(mainSocket, (struct sockaddr*)&clientAddr, &clientAddrLength)) < 0){
            perror("ERROR DURING CONNECTION");
            continue;
        }

        pthread_t *newThread;
        pthread_create(&newThread, NULL, newClient, (void*)newSocket);
        pthread_detach(newThread);
    }

    return EXIT_SUCCESS;

}

void *newClient(void *argSocket){

    fflush(stdout);
    int socketId = (int)argSocket;
    while(1){
        char command[MAXCOMMAND];
        memset(command, '\0', MAXCOMMAND);

        for(int i = 0;i<MAXCOMMAND;i++){
            int answer = recv(socketId, &command[i], 1, 0);
            if(answer==0)       
                break;
            if(answer<0)
                break;
            if(command[i]=='\n')
                break;
        }

        int commandLength = strlen(command);

        if(commandLength > 0 && command[commandLength-1] == '\n'){
            command[commandLength-1] = '\0';
            if(commandLength-2 >= 0 && command[commandLength-2] == '\r')
                command[commandLength-2] = '\0';
        }

        if(commandLength == 0)
            continue;

        printf("NEW COMMAND: %s\n", command);
        fflush(stdout);

        FILE *result = popen(command, "r");

        if(result != NULL)
            while(1){
                char buffer[BUFFSIZE];
                memset(buffer, '\0', BUFFSIZE);
                char *pipeData = fgets(buffer, BUFFSIZE, result);
                if(pipeData == NULL)
                    break;
                int r = send(socketId, buffer, strlen(buffer), 0);
                r = send(socketId, '\n', 1, 0);
                if(r <= 0)
                    break;
            }
    }

    end:
    printf("END\n");

}
服务器工作正常,接收并重新发送linux命令结果,但java客户端只在我关闭服务器时接收应答并填充文本区域。 否则客户会被绞死。。。 我在Oracle VM和Java 1.8上使用带有gcc的Ubuntu虚拟机。
我的错误是什么?

原始代码有以下行来检查是否应继续接收:

while ((response = reader.readLine()) != null){
问题是,只有在对等方关闭连接后,才会返回null。用户界面的更新仅在方法返回后发生。因此,UI仅在连接关闭时更新

必须有某种结束标记来表示从服务器到最后一个请求(本例中为命令)不再有数据,这样while循环才能结束

如果Java端是这样实现的,代码应该可以工作

while (!"".equals(response = reader.readLine())){
if(result != NULL) {
    while(1){
        char buffer[BUFFSIZE];
        memset(buffer, '\0', BUFFSIZE);
        char *pipeData = fgets(buffer, BUFFSIZE, result);
        if(pipeData == NULL)
            break;
        int r = send(socketId, buffer, strlen(buffer), 0);
        if(r <= 0) break;           
    }
}
send(socketId, "\n", 1, 0);        
C面像这样

while (!"".equals(response = reader.readLine())){
if(result != NULL) {
    while(1){
        char buffer[BUFFSIZE];
        memset(buffer, '\0', BUFFSIZE);
        char *pipeData = fgets(buffer, BUFFSIZE, result);
        if(pipeData == NULL)
            break;
        int r = send(socketId, buffer, strlen(buffer), 0);
        if(r <= 0) break;           
    }
}
send(socketId, "\n", 1, 0);        
if(结果!=NULL){
而(1){
字符缓冲区[BUFFSIZE];
memset(缓冲区'\0',BUFFSIZE);
char*pipeData=fgets(缓冲区、BUFFSIZE、结果);
if(pipeData==NULL)
打破
int r=send(socketId,buffer,strlen(buffer),0);

if(r readLine method从不返回字符'\n'。它返回字符串。现在(如果我的假设正确的话),即使服务器关闭,textarea也不会更新。简单的方法是在输出结束时添加带有END的行。然后检查是否为“END”等于readline.Aa…的结果,但您可以检查该行是否为空。因为您正在发送empy行。这在while(“.”等于(response=reader.readline())时发生。更简单的解决方案是服务器在发送完所有数据后关闭连接。当然,如果客户端想发送另一个命令,则需要重新连接。我不想断开与服务器的连接,这个(“.”equals(response=reader.readLine())不起作用,第一个空格和第二个空格。选项带while(!(response=reader.readLine())).equals(“end”)也不起作用。抱歉。while(“.equals(…)当然错了,因为我忘了否定条件。很高兴你让它起作用了。