UNIX fork() 之后的 printf()

printf() after UNIX fork()

我正在研究一个非常基本的客户端服务器通信服务,只是为了学习这个概念。 在服务器端,我有一个接受连接并让客户端与服务器通信的功能。每当连接的客户端向服务器发送消息时,它都会向客户端发送响应消息。 在客户端,我创建了一个线程来侦听来自服务器的 messages/responses。该线程只是运行一个循环,检查 read() returns 是否超过 0 个字节,如果是,它会打印消息。其他线程处理用户输入并向服务器发送消息。

现在回答问题: 我有几行代码可以监听来自服务器的消息

void readFromServer(int fileDescriptor)
{
    int nOfBytes;
    char buffer[512];
    while(1){
        nOfBytes = read(fileDescriptor, buffer, 512);
        if(nOfBytes > 0)
            printf("Server says: %s \n\n>", buffer);
    }
}

这意味着当一条消息来自服务器时,我想像这样表示它

>Serever says: Something

>|

但出于某种原因,我得到的是这个

>>Server says: Something

|

(|管道表示控制台中的光标window)

有谁知道这是为什么?这个问题有什么解决办法吗?

提前致谢。

编辑------------> fork() 是在主函数中完成的,就像这样

int pid = fork();
if(pid != 0)
    readFromServer(sock);

很可能 stdio 缓冲会妨碍。要使 stdout 无缓冲,请使用

setvbuf(stdout, 0, _IONBF, 0);

开始前一次 I/O。这是一个 C89 函数,在 <stdio.h> 中声明。您的 manual page 包含所有详细信息。

您正在从一个线程写出输入提示“>”,而从另一个线程写出服务器语句。

要实现您想要的 UI,您需要投资开发 curses(或 termcap)技术,以及线程同步或 select() 系统调用以从键盘和套接字。

示例输出中的双 > 未由您提供的代码解释。可能您的其他线程也在打印到 stdout.

末尾缺少 > 几乎可以肯定是因为 stdout 默认情况下是行缓冲的,这意味着它会累积输出直到收到换行符,并一次打印一行时间。您可以按照 Jens 的建议通过禁用缓冲或在打印后调用 fflush(stdout) 来解决此问题。

也请注意,您对 read() 的使用是有问题的。不一定能在一次调用中从另一端读取整条消息,即使该消息小于您指定的 512 字节。此外,如果另一方关闭网络连接,您的循环将进入旋转状态,每个 read() 调用都会立即返回 -1 而不会阻塞。