在从Java服务器等待数据时,Linux read()阻塞

时间:2013-04-15 16:04:56

标签: c++ linux sockets

您好,并提前致谢。我有一个Java程序和一个通过套接字进行通信的C ++ Linux程序。当从Java端向C ++端发送数据时,C ++程序在等待数据时阻塞read()调用,而Java程序阻塞PrintWriter对象上的write()调用。但是,我可以将数据从C ++发送到Java。尽管经过了数天的研究和测试,但我不明白为什么会这样。

这是我试图从套接字读取的C ++代码:

int sockfd;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[10] = "20\n";

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if(sockfd < 0) {
    perror("Error: cannot create socket");
    return 1;
}

server = gethostbyname("localhost");
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(2500);

if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
    std::cout << "Error: connection could not be established" << std::endl;
    return 1;
}
int n = write(sockfd, buffer, strlen(buffer));
if(n < 0) {
    perror("Error: could not write to socket");
    return 1;
}

n = read(sockfd, p_read_location, 1);
if(n < 0) {
    perror("Error: could not read from socket");
    return 1;
}

close(sockfd);

return 0;

正如您所看到的,我向流向Java端的流写了几个字符,然后等待接收一个字符。变量p_read_location是传递给该函数的指针,该函数包含足够的空间来保存读取的内容。 read()的第三个参数,即要读取的字节数,似乎不会影响问题。

以下是Java程序中的相关类:

public class Parser {
private Socket connection;
private BufferedReader br;
private PrintWriter pw;
private String data;
private char mode;
private char algorithm;
private Job job;

public Parser() {
    data = new String();
}

public void readData(Socket p_connection) {
    connection = p_connection;

    try {
        br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        pw = new PrintWriter(connection.getOutputStream(), true);
        String line;

        line = br.readLine();
        mode = line.charAt(0);
        algorithm = line.charAt(1);

        while((line = br.readLine()) != null) {
            data += line;
        }

        process();
    }
    catch (Exception ex) {
        System.err.printf("Exception in stream reading: %s\n", ex.getMessage());
    }
}

private void process() {
    switch(mode) {
    case '1':                           //New data
        job = new Job(data);
        break;
    case '2':                           //Status request
        try {
            System.out.println("DEBUG");
            pw.write("TEST\n");
        } 
        catch (Exception e) {
            System.err.println("Exception writing status info to socket (in parser): " + e.getMessage());
        }
        break;
    default:
        System.err.println("Parser could not interpret command (received code '" + mode + "')");
        break;
    }

    try {
        pw.close();
        br.close();
        connection.close();
    } 
    catch (IOException e) {
        System.err.printf("Error closing the connection: %s\n", e.getMessage());
    }
}

}

该程序从套接字读取第一行,其中包含几个字符,然后(应该)在(mode == 2)时将“TEST \ n”写回套接字。我已经验证模式设置为2并且正在执行“2”块。

有趣的是,“DEBUG”仅在套接字关闭后写入标准输出,即使声明

System.out.println("DEBUG");

在调用pw.write()之前出现。

我在PrintWriter和底层的OutputStream上尝试过flush()调用,我尝试通过套接字发送的所有内容都以'\ n'结尾。

我感谢任何帮助/评论。

感谢。

0 个答案:

没有答案