unix域套接字非常慢

时间:2017-11-02 02:07:14

标签: c linux sockets unix unix-socket

我得到了代码(client; server),需要在进程之间非常快速地传输数据(模拟可扩展的内存总线;实际上我尝试拆分"游戏卡带模拟&# 34;部分来自游戏系统仿真"游戏模拟器的一部分,以便更容易实现/测试/调试/等更多虚拟和真实硬件。

为此,我使用SOCK_SEQPACKET选择了unix域套接字。

没有错误处理的简短示例:

typedef struct {
  enum {
    CONNECT,
    CONNECT_RESP,
    //... a few more packet types
  } type;
  uint16_t addr;
  uint16_t len; //note this is not the packet length, but a length field for a specific operation omitted for simplicity in the type field above
  uint8_t value;
} packet;

int server_main(int argc, char *argv[]) {
  const char* socket_path= "\0de.nonchip.PlutoBoy.hook_mem";
  int fd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
  struct sockaddr_un addr;
  memset(&addr, 0, sizeof(addr));
  addr.sun_family = AF_UNIX;
  *addr.sun_path = '\0';
  strncpy(addr.sun_path+1, socket_path+1, sizeof(addr.sun_path)-2);
  size_t psize=sizeof(packet);
  setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &psize, sizeof(psize));
  bind(fd, (struct sockaddr*)&addr, sizeof(addr));
  listen(fd, 5);
  packet p;
  while(1){
    int cl = accept(fd, NULL, NULL));
    while(recv(cl,&p,psize,MSG_WAITALL)>0){
      if(p.type==CONNECT)
        p.type=CONNECT_RESP;
      send(cl,&p,psize,MSG_EOR);
    }
  }
}

//----

void client_connect_socket(){
  const char* socket_path = "\0de.nonchip.PlutoBoy.hook_mem";
  struct sockaddr_un socket_addr;
  int socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0)
  memset(&socket_addr, 0, sizeof(socket_addr));
  socket_addr.sun_family = AF_UNIX;
  *socket_addr.sun_path = '\0';
  strncpy(socket_addr.sun_path+1, socket_path+1, sizeof(socket_addr.sun_path)-2);

  setsockopt(socket_fd, SOL_SOCKET, SO_SNDBUF, &psize, sizeof(psize));
  connect(socket_fd, (struct sockaddr*)&socket_addr, sizeof(socket_addr));

  packet p;
  p.type=CONNECT;
  send(socket_fd, &p, psize,MSG_EOR);
  recv(socket_fd, &p, psize,MSG_WAITALL);
  if(p.type != CONNECT_RESP){
    perror("connect handshake error");
    exit(-1);
  }
}

但是这样做得非常慢,并且驱使我的系统负载达到正常值的3-4倍左右,所以我决定为它添加原始基准测试(使用CLOCK_MONOTONIC和字节计数器),这给了我:

  211091 bytes transferred in  5 s =    42218 B/s
  213748 bytes transferred in  5 s =    42749 B/s
  213062 bytes transferred in  5 s =    42612 B/s
  215458 bytes transferred in  5 s =    43091 B/s
  219934 bytes transferred in  5 s =    43986 B/s
  210272 bytes transferred in  5 s =    42054 B/s
  216723 bytes transferred in  5 s =    43344 B/s

如何通过unix域套接字在抢占式内核上的两个进程之间的连接只有~42KB / s?这是非常正常还是我错过了一些关键的东西?

编辑:我创建了一些clientserver的调用日志日志,但是看不到任何真正阻止我的内容。

0 个答案:

没有答案