如何closureswrite()系统调用的缓冲?

我曾经认为write()系统调用是无缓冲的, fwritefread用于缓冲IO。 不过,我写了一些简单的程序来确定在使用write()时仍然有一些缓冲。 我在套接字上使用write()read() 。 由于缓冲,服务器不停地发送数据包时,客户端可能会滞后。 我不要那个。 我希望客户端必须在服务器发送更多logging之前消耗logging。

我怎样才能做到这一点,而不增加确认等networking负载!

我在linux上使用gcc

server.c:

 #include <stdio.h> #include <errno.h> #include <sys/socket.h> #include <arpa/inet.h> #include <stdio.h> #include <netinet/in.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <netinet/tcp.h> int remote_rr_port=2000; // Server will send RR logs using connection on this port. char const *remote_server_ip="127.0.0.1"; int connFD_rr; static void startTcpServer(int *sd, const int port) { *sd= socket(AF_INET, SOCK_STREAM, 0); // Set socket option so that port can be reused int enable = 1; setsockopt(*sd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)); struct sockaddr_in a; memset(&a,0,sizeof(a)); a.sin_family = AF_INET; a.sin_port = port; a.sin_addr.s_addr = INADDR_ANY; int bindResult = bind(*sd, (struct sockaddr *) &a, sizeof(a)); listen(*sd,2); } // Wait for connection from client static int getTcpConnection(int sd) { char buf[100]; socklen_t len; struct sockaddr_in clientAddress; printf("\nWaiting for connection from remote client\n"); len = sizeof(clientAddress); int connFD = accept(sd, (struct sockaddr*) &clientAddress, &len); setsockopt(connFD_rr, SOL_SOCKET, SO_SNDBUF, (int[]){0}, sizeof(int)); printf("\n Connection from : %s:%d\n",inet_ntop(AF_INET, &clientAddress.sin_addr, buf, sizeof(buf)),clientAddress.sin_port); fflush(stdout); return connFD; } FILE* rdrr_server_start(void) { // Socket Descriptors for the two connections int rr_sd; int input_sd; startTcpServer(&rr_sd, remote_rr_port); connFD_rr = getTcpConnection(rr_sd); return fdopen(connFD_rr, "w"); } int main() { int i = 0; rdrr_server_start(); for(i=0;i<10000000; i++) { write(connFD_rr, &i, sizeof (int)); printf("%d\n", i); } return 0; } 

client.c:

 #include <sys/socket.h> #include <arpa/inet.h> #include <stdio.h> #include <netinet/in.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <netinet/tcp.h> int remote_rr_port=2000; // Server will send RR logs using connection on this port. char const *remote_server_ip="127.0.0.1"; int connFD_rr; FILE* rdrr_client_start(void) { connFD_rr = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in a; memset(&a,0,sizeof(a)); a.sin_family = AF_INET; a.sin_port = remote_rr_port; a.sin_addr.s_addr = inet_addr(remote_server_ip); printf("\nConnecting to Server on RR port"); int CONNECT_TO_SERVER= connect(connFD_rr,(struct sockaddr *) &a, sizeof(a)); printf("\nConnected to server on RR port"); setsockopt(connFD_rr, SOL_SOCKET, SO_RCVBUF, (int[]){0}, sizeof(int)); return fdopen(connFD_rr, "r"); } int main() { int i = 0; rdrr_client_start(); getrchar(); while(1) { read(connFD_rr, &i, sizeof (int)); printf("%d\n", i); } return 0; } 

Solutions Collecting From Web of "如何closureswrite()系统调用的缓冲?"

也许你的意思是你想要禁用Nagle的算法,在这种情况下解决方案是:

 setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (int[]){1}, sizeof(int)); 

编辑:嗯,它看起来像你想要比这更多,我怀疑你想要什么可能没有设计自己的协议在UDP之上。

编辑2:通过限制发送和接收缓冲区的大小,你可能会得到一个类似于你想要的效果。 服务器(发件人)应该这样做:

 setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (int[]){YOUR_BUF_LIMIT}, sizeof(int)); 

和客户端(接收者)应该这样做:

 setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (int[]){YOUR_BUF_LIMIT}, sizeof(int));