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 而不会阻塞。
我正在研究一个非常基本的客户端服务器通信服务,只是为了学习这个概念。 在服务器端,我有一个接受连接并让客户端与服务器通信的功能。每当连接的客户端向服务器发送消息时,它都会向客户端发送响应消息。 在客户端,我创建了一个线程来侦听来自服务器的 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 而不会阻塞。