Comment désactiver la mise en mémoire tampon sur l’appel système write ()?

J’avais l’habitude de penser que l’appel système write() n’est pas mis en mémoire tampon et que fwrite et fread sont utilisés pour les entrées-sorties en mémoire tampon. Cependant, j’ai écrit des programmes simples pour établir qu’il restait de la mémoire tampon lors de l’utilisation de write() . J’utilise write() et read() sur des sockets. En raison de la mise en mémoire tampon, il est possible que le client soit à la traîne pendant que le serveur continue à envoyer des paquets. Je ne veux pas ça. Je veux que le client doit consumr l’enregistrement avant que le serveur envoie plus d’enregistrements.

Comment puis-je y arriver sans append une charge réseau d’accusés de réception, etc.!

J’utilise gcc sur linux

server.c:

 #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  #include  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  #include  #include  #include  #include  #include  #include  #include  #include  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; } 

Peut-être que ce que vous voulez dire, c’est que vous voulez désactiver l’algorithme de Nagle, auquel cas la solution est:

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

Edit: Hum, on dirait que vous voulez plus que cela, et je doute que ce que vous voulez soit possible sans concevoir votre propre protocole sur UDP.

Edit 2: Vous pourrez peut-être obtenir un effet similaire à ce que vous voulez en limitant la taille des tampons d’envoi et de réception. Le serveur (expéditeur) doit faire:

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

et le client (destinataire) doit faire:

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