How to disable buffering on a write () system call?

I used to think that the write() system call was unbuffered and that fwrite and fread are used for buffered I / O. However, I wrote simple programs to establish that buffering still occurs when using write() . I use write() and read() for sockets. Due to buffering, the client may lag while the server continues to send packets. I dont need it. I want the client to have to use the record before the server sends more records.

How can I do this without adding a network load of confirmations, etc.!

I am using gcc for linux

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; } 
+4
source share
1 answer

Perhaps you mean that you want to disable Nagle Algorithm , in which case this solution:

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

Edit: Hmm, it looks like you want more than that, and I doubt what you want without creating your own protocol on top of UDP.

Edit 2:. You can get an effect similar to what you want by limiting the size of the send and receive buffer. The server (sender) must complete:

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

and the client (recipient) must:

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

Source: https://habr.com/ru/post/1393911/


All Articles