读取仅返回C UNIX插座的系统呼叫,并在检测到新线路时触发。这是默认行为吗?

发布于 2025-01-26 06:12:13 字数 2326 浏览 3 评论 0原文

我一直在阅读的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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无人问我粥可暖 2025-02-02 06:12:13

问题在于您打印字符的方式,而不是您如何接收数据。

默认情况下,当stdout(其中printf写入)连接到交互式终端时,它将为 line buffered。这意味着将所有写入stdout的输出将被缓冲到四个事情中的任何一个:

  1. 缓冲区已满
  2. 已明确冲洗(使用fflush(stdout))
  3. 。缓冲区 编写newline
  4. 如果您收到的数据不包含newline,则该过程退出

,则将其保存在缓冲区中,而不会写入实际终端。

解决方案很简单:编写一个newline或调用fflush(stdout)

The problem is in how you print the characters, not about how you receive the data.

By default, when stdout (where printf writes) is connected to an interactive terminal, it will be line buffered. That means all output written to stdout will be buffered until either one of four things happens:

  1. The buffer is full
  2. The buffer is explicitly flushed (with fflush(stdout))
  3. There's a newline being written
  4. The process exits

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文