Telnet和C服务器:未清除的流
我创建了一个有效的连接,两个有效的文件tx(发送)和rx(接收),并尝试接收telnet发送的日期,并将数据发送到telnet。 这是关键代码部分: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);
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);
}