簡體   English   中英

如何關閉write()系統調用的緩沖?

[英]How to turn off buffering on write() system call?

我以前認為write()系統調用是無緩沖的,而fwritefread用於緩沖IO。 但是我編寫了簡單的程序來確定在使用write()時仍然會進行一些緩沖。 我在套接字上使用write()read() 由於緩沖,客戶端可能會在服務器不斷發送數據包時滯后。 我不要那個。 我希望客戶端必須在服務器發送更多記錄之前使用該記錄。

如何在不增加網絡負載的確認等的情況下實現這一目標!

我在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;
} 

也許你的意思是你要禁用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));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM