读取仅返回C UNIX插座的系统呼叫,并在检测到新线路时触发。这是默认行为吗?
我一直在阅读的Internet和书籍上的来源似乎并未准确指定UNIX读取系统呼叫的行为以及何时触发。他们只是说,一旦从另一端发送数据,该数据就可以在读取中消费,并且一旦收到EOF信号(例如,由于鳍)即可返回-1。
1)仅在发送包含新的行字符的数据时才触发此服务器中的读取?
2)为什么未检测到读取\ n ?
3)如果我试图扭转情况(服务器发送数据,客户读取这种情况不会发生?
4)怎么办? 4)在我的操作系统上使用一些TCP/IP协议堆栈设置来处理,该设置分别应用于客户端或服务器时设置不同的行为?
这是服务器:
#define PORT 1026
int main(){
int sockfd, connfd;
unsigned int len;
struct sockaddr_in servaddr, cli;
//SOCKET CREATION
sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr =htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
//BIND
if ((bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n");
exit(0);
}
//LISTEN
if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
}
for(;;){
len = sizeof(cli);
connfd = accept(sockfd, (struct sockaddr*)&cli, &len);
if (connfd < 0) {
printf("server accept failed...\n");
exit(0);
}else{
printf("New connection accepted !\n");
}
char buffr;
int r;
while( (r=read(connfd,&buffr,sizeof(buffr))) > 0 ){
if(buffr=='#') break;
printf("%c",buffr);
};
close(connfd);
};
return 0;
}
这是客户端发送数据:
#define PORT 1026
int main(){
int sockfd;
struct sockaddr_in servaddr, cli;
//CREATE SOCKET
sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) != 0) {
printf("connection with the server failed...\n");
//exit(0);
}
char s[]="Hello World !#"; // DOESN'T WORK !
/*char s[]="Hello World !#\n"; DOES WORK*/
write(sockfd,s,sizeof(s));
close(sockfd);
return 0;
}
我正在使用Mac OS而且我还检查了Wireshark流量,看来数据包没有问题。那么,这是怎么回事?
The sources on the Internet and books I've been reading seem to not specify exactly how the unix read system call behaves and when exactly it is triggered. They simply say that as soon as data are sent from the other end this data are available for consuming with the read and as soon as the EOF signal is received ( for example because of FIN ) the returns -1.
1) How come that the read in this server is ONLY triggered when data are sent that include an \n new line character ?
2) Why does the read get stuck if \n is not detected ?
3) How come that if I try to reverse the situation ( the server sends data and the client reads it this situation doesn't occur ?
4) Has this behaviour something to do with some TCP/IP protocol stack settings on my OS that set different behaviours when read is applied to client or server respectively?
This is the server :
#define PORT 1026
int main(){
int sockfd, connfd;
unsigned int len;
struct sockaddr_in servaddr, cli;
//SOCKET CREATION
sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr =htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
//BIND
if ((bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr))) != 0) {
printf("socket bind failed...\n");
exit(0);
}
//LISTEN
if ((listen(sockfd, 5)) != 0) {
printf("Listen failed...\n");
exit(0);
}
for(;;){
len = sizeof(cli);
connfd = accept(sockfd, (struct sockaddr*)&cli, &len);
if (connfd < 0) {
printf("server accept failed...\n");
exit(0);
}else{
printf("New connection accepted !\n");
}
char buffr;
int r;
while( (r=read(connfd,&buffr,sizeof(buffr))) > 0 ){
if(buffr=='#') break;
printf("%c",buffr);
};
close(connfd);
};
return 0;
}
And this is the client sending data :
#define PORT 1026
int main(){
int sockfd;
struct sockaddr_in servaddr, cli;
//CREATE SOCKET
sockfd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if (sockfd == -1) {
printf("socket creation failed...\n");
exit(0);
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(PORT);
if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) != 0) {
printf("connection with the server failed...\n");
//exit(0);
}
char s[]="Hello World !#"; // DOESN'T WORK !
/*char s[]="Hello World !#\n"; DOES WORK*/
write(sockfd,s,sizeof(s));
close(sockfd);
return 0;
}
I'm using Mac OS and I've also checked on the wireshark traffic and it seems there are no problems with the packets. So, what's going on here ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于您打印字符的方式,而不是您如何接收数据。
默认情况下,当
stdout
(其中printf
写入)连接到交互式终端时,它将为 line buffered。这意味着将所有写入stdout
的输出将被缓冲到四个事情中的任何一个:fflush(stdout
)),则将其保存在缓冲区中,而不会写入实际终端。
解决方案很简单:编写一个newline或调用
fflush(stdout)
。The problem is in how you print the characters, not about how you receive the data.
By default, when
stdout
(whereprintf
writes) is connected to an interactive terminal, it will be line buffered. That means all output written tostdout
will be buffered until either one of four things happens:fflush(stdout
))If the data you receive doesn't contain a newline, then it will be kept in the buffer and not written to the actual terminal.
The solution is simple: Write a newline, or call
fflush(stdout)
.