什么可能是套接字读取速度非常慢的原因?

Ank*_*rVj 5 c sockets tcp blocking

我正在为我的客户端和服务器使用阻塞TCP套接字.每当我阅读时,我首先检查流上的数据是否可用select.我总是一次读写40个字节.虽然大多数读取需要几毫秒或更短,但有些只需要超过半秒.在我知道套接字上有可用数据之后.

我也在用 TCP_NODELAY

可能是什么原因造成的?

编辑2

我分析了发送和接收的每个数据包的时间戳,并发现只有当客户端在服务器写入下一个对象之前尝试读取对象时才会发生此延迟.例如,服务器写入对象编号x,之后客户端尝试读取对象x,然后服务器才能开始编写对象编号x + 1.这让我怀疑服务器端正在进行某种合并.

编辑

服务器正在侦听3个不同的端口.客户端逐个连接到每个端口.

有三个连接:一个连接从服务器经常向客户端发送一些数据.第二个只从客户端向服务器发送数据.第三个很少用于发送单字节数据.我正面临着第一次连接的问题.我正在检查使用select()该连接上的数据,然后当我为40字节读取时间戳时,我发现该读取大约需要半秒钟.

关于如何分析这个的任何指示都会非常有帮助

在linux上使用gcc.

rdrr_server_start(void) {
int rr_sd; int input_sd; int ack_sd; int fp_sd;

startTcpServer(&rr_sd, remote_rr_port); startTcpServer(&input_sd, remote_input_port); startTcpServer(&ack_sd, remote_ack_port); startTcpServer(&fp_sd, remote_fp_port);

connFD_rr = getTcpConnection(rr_sd); connFD_input = getTcpConnection(input_sd); connFD_ack= getTcpConnection(ack_sd); connFD_fp=getTcpConnection(fp_sd); }

static int getTcpConnection(int sd) { socklen_t l en;
struct sockaddr_in clientAddress; len = sizeof(clientAddress); int connFD = accept(sd, (struct sockaddr*) &clientAddress, &len); nodelay(connFD); fflush(stdout); return connFD; }

static void startTcpServer(int *sd, const int port) { *sd= socket(AF_INET, SOCK_STREAM, 0); ASSERT(*sd>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)); ASSERT(bindResult ==0); listen(*sd,2); } static void nodelay(int fd) { int flag=1; ASSERT(setsockopt(fd, SOL_TCP, TCP_NODELAY, &flag, sizeof flag)==0); }

startTcpClient() { connFD_rr = socket(AF_INET, SOCK_STREAM, 0); connFD_input = socket(AF_INET, SOCK_STREAM, 0); connFD_ack = socket(AF_INET, SOCK_STREAM, 0); connFD_fp= 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);

int CONNECT_TO_SERVER= connect(connFD_rr, &a, sizeof(a)); ASSERT(CONNECT_TO_SERVER==0) ;

a.sin_port = remote_input_port; CONNECT_TO_SERVER= connect(connFD_input, &a, sizeof(a)); ASSERT(CONNECT_TO_SERVER==0) ;

a.sin_port = remote_ack_port; CONNECT_TO_SERVER= connect(connFD_ack, &a, sizeof(a)); ASSERT(CONNECT_TO_SERVER==0) ;

a.sin_port = remote_fp_port; CONNECT_TO_SERVER= connect(connFD_fp, &a, sizeof(a)); ASSERT(CONNECT_TO_SERVER==0) ;

nodelay(connFD_rr); nodelay(connFD_input); nodelay(connFD_ack); nodelay(connFD_fp); }

rdrr_server_start(void) {
int rr_sd; int input_sd; int ack_sd; int fp_sd;

startTcpServer(&rr_sd, remote_rr_port); startTcpServer(&input_sd, remote_input_port); startTcpServer(&ack_sd, remote_ack_port); startTcpServer(&fp_sd, remote_fp_port);

connFD_rr = getTcpConnection(rr_sd); connFD_input = getTcpConnection(input_sd); connFD_ack= getTcpConnection(ack_sd); connFD_fp=getTcpConnection(fp_sd); }

static int getTcpConnection(int sd) { socklen_t l en;
struct sockaddr_in clientAddress; len = sizeof(clientAddress); int connFD = accept(sd, (struct sockaddr*) &clientAddress, &len); nodelay(connFD); fflush(stdout); return connFD; }

static void startTcpServer(int *sd, const int port) { *sd= socket(AF_INET, SOCK_STREAM, 0); ASSERT(*sd>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)); ASSERT(bindResult ==0); listen(*sd,2); } static void nodelay(int fd) { int flag=1; ASSERT(setsockopt(fd, SOL_TCP, TCP_NODELAY, &flag, sizeof flag)==0); }

select

startTcpClient() { connFD_rr = socket(AF_INET, SOCK_STREAM, 0); connFD_input = socket(AF_INET, SOCK_STREAM, 0); connFD_ack = socket(AF_INET, SOCK_STREAM, 0); connFD_fp= 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);

int CONNECT_TO_SERVER= connect(connFD_rr, &a, sizeof(a)); ASSERT(CONNECT_TO_SERVER==0) ;

a.sin_port = remote_input_port; CONNECT_TO_SERVER= connect(connFD_input, &a, sizeof(a)); ASSERT(CONNECT_TO_SERVER==0) ;

a.sin_port = remote_ack_port; CONNECT_TO_SERVER= connect(connFD_ack, &a, sizeof(a)); ASSERT(CONNECT_TO_SERVER==0) ;

a.sin_port = remote_fp_port; CONNECT_TO_SERVER= connect(connFD_fp, &a, sizeof(a)); ASSERT(CONNECT_TO_SERVER==0) ;

nodelay(connFD_rr); nodelay(connFD_input); nodelay(connFD_ack); nodelay(connFD_fp); }

小智 0

一个客户端和多个连接?

某些套接字函数可能会阻止您的执行(即等待函数的结果)。我建议为每个连接打开一个新线程(在服务器端),这样它们就不会互相干扰......

但我是在黑暗中拍摄;您需要发送一些附加信息...