Telnet和C服务器:未清除的流

Telnet和C服务器:未清除的流,c,server,stream,telnet,C,Server,Stream,Telnet,我创建了一个有效的连接,两个有效的文件tx(发送)和rx(接收),并尝试接收telnet发送的日期,并将数据发送到telnet。 这是关键代码部分: for(i = 0; i < 3; i++){ fprintf(tx, "Send me a message\n"); while(1){ c = fgetc(rx); fputc(c, stdout);

我创建了一个有效的连接,两个有效的文件tx(发送)和rx(接收),并尝试接收telnet发送的日期,并将数据发送到telnet。 这是关键代码部分:

for(i = 0; i < 3; i++){
            fprintf(tx, "Send me a message\n");
            while(1){
                c = fgetc(rx);
                fputc(c, stdout);
                if(c == '\n')
                    break;
            }
            fprintf(tx, "Thank you! \n");
}
但是,看看我的代码,我本来希望看到:

Send a message
Hello
Thank you!
Send a message
How are you
Thank you!
...
为什么telnet只在服务器终止时打印日期

完整代码:

#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

static const int LISTEN_PORT = 2017;


static void die(const char *msg){
    perror(msg);
    exit(EXIT_FAILURE);
}

int main (void){
    int sockfd, flag;
    flag = 1;
    struct sockaddr_in6 host_addr;

    sockfd = socket(PF_INET6, SOCK_STREAM, 0);
    if(sockfd == -1)
        die("socket");

    host_addr.sin6_family = AF_INET6;
    host_addr.sin6_port = htons(2017);
    host_addr.sin6_addr = in6addr_any;

    if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int))
    == -1)
        die("setsockopt");

    if(bind(sockfd, (const struct sockaddr *)&host_addr, 
        sizeof(host_addr)) ==  -1)
        die("bind");
    if(listen(sockfd, SOMAXCONN) == -1)
        die("listen");

    while(1){
        int client = accept(sockfd, NULL, NULL);

        if(client == -1)
            die("accept");

        int client2 = dup(client);

        if(client2 == -1)
            die("dup");
        FILE *tx;
        FILE *rx;

        tx = fdopen(client, "w");
        rx = fdopen(client2, "r");

        if(!tx || !rx)
            die("fdopen");
        int c;
        int i;
        for(i = 0; i < 3; i++){
            fprintf(tx, "Send me a message\n");
            while(1){
                c = fgetc(rx);
                fputc(c, stdout);
                if(c == '\n')
                    break;
            }
            fprintf(tx, "Thank you! \n");
        }
        break;
    }
    exit(EXIT_SUCCESS);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
静态常数int LISTEN_PORT=2017;
静态空模(常量字符*msg){
佩罗尔(味精);
退出(退出失败);
}
内部主(空){
int sockfd,flag;
flag=1;
6主机地址中的结构sockaddr\u;
sockfd=套接字(PF_INET6,SOCK_流,0);
如果(sockfd==-1)
模具(“插座”);
host_addr.sin6_family=AF_INET6;
主机地址sin6端口=htons(2017年);
host_addr.sin6_addr=in6addr_any;
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(int))
== -1)
模具(“固定锁”);
if(绑定(sockfd,(常量结构sockaddr*)和主机地址,
sizeof(主机地址))=-1)
死亡(“捆绑”);
如果(侦听(sockfd,SOMAXCONN)=-1)
死(“听”);
而(1){
int client=accept(sockfd,NULL,NULL);
如果(客户端==-1)
死亡(“接受”);
int client2=dup(客户端);
如果(客户端2==-1)
死亡(“dup”);
文件*tx;
文件*rx;
tx=fdopen(客户,“w”);
rx=fdopen(客户端2,“r”);
如果(!tx | |!rx)
模具(“fdopen”);
INTC;
int i;
对于(i=0;i<3;i++){
fprintf(tx,“发送消息给我”);
而(1){
c=fgetc(rx);
fputc(c,stdout);
如果(c=='\n')
打破
}
fprintf(tx,“谢谢!\n”);
}
打破
}
退出(退出成功);
}

另外,如果有人能改进我问题的标题,我想其他有此问题的人不会这么容易发现。只是猜测一下,也许你必须用fflush(tx)刷新tx流;是的,我也是这么想的,这就是为什么我用我的方式来命名这个问题。但是我不知道fflush()实际上做什么以及如何使用它。@Josch Kraus,文件流是缓冲的,因此如果不刷新,您就无法直接控制数据何时实际写入文件,或者在您的情况下写入套接字。可能发生的情况如下:写入文件流,数据被缓冲,当程序终止时,文件流和套接字被自动刷新。您可以通过在终止之前对文件流调用fclose()来测试这一点,只需在fclose()之前放置一个getchar()。解决了它。您是否有任何来源可以让我了解更多关于哪些I/O机制是缓冲的,哪些机制将直接传输到文件/流?
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

static const int LISTEN_PORT = 2017;


static void die(const char *msg){
    perror(msg);
    exit(EXIT_FAILURE);
}

int main (void){
    int sockfd, flag;
    flag = 1;
    struct sockaddr_in6 host_addr;

    sockfd = socket(PF_INET6, SOCK_STREAM, 0);
    if(sockfd == -1)
        die("socket");

    host_addr.sin6_family = AF_INET6;
    host_addr.sin6_port = htons(2017);
    host_addr.sin6_addr = in6addr_any;

    if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(int))
    == -1)
        die("setsockopt");

    if(bind(sockfd, (const struct sockaddr *)&host_addr, 
        sizeof(host_addr)) ==  -1)
        die("bind");
    if(listen(sockfd, SOMAXCONN) == -1)
        die("listen");

    while(1){
        int client = accept(sockfd, NULL, NULL);

        if(client == -1)
            die("accept");

        int client2 = dup(client);

        if(client2 == -1)
            die("dup");
        FILE *tx;
        FILE *rx;

        tx = fdopen(client, "w");
        rx = fdopen(client2, "r");

        if(!tx || !rx)
            die("fdopen");
        int c;
        int i;
        for(i = 0; i < 3; i++){
            fprintf(tx, "Send me a message\n");
            while(1){
                c = fgetc(rx);
                fputc(c, stdout);
                if(c == '\n')
                    break;
            }
            fprintf(tx, "Thank you! \n");
        }
        break;
    }
    exit(EXIT_SUCCESS);
}