Nhờ mọi người giúp mình vấn đề này với. Mình đang code thử một chương trình giao tiếp với thiết bị ngoại vi sử dụng tcp socket. App của mình đóng vai trò là server socket.
Khi nhận được data từ client gửi lên, mình sẽ gửi phản hồi lại cho client, sử dụng hàm:
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
buffer length của mình (khoảng 4kB) > MTU (1500 byte) nên TCP chia nhỏ thành các packet nhỏ hơn. Mình dùng wireshark để bắt gói tin thì thấy thời gian gửi giữa các packet nhỏ cách nhau khoảng 0,3s. Nếu gửi số lượng lớn (khoảng vài chục Mb) thời gian gửi rất lâu ~ vài tiếng.
Nhờ mọi người giúp mình vấn đề này với T_T
P/s: Mình đã thử set lại socket option TCP_NODELAY mà vẫn không ăn thua.
EDIT:
Đây là file tcpdump của mình. Phần đánh dấu đỏ là thời gian gửi tcp frame trong một lần gọi hàm send() của mình. Cách nhau ~0.2s.
Đây là code của mình:
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
void createServerSocket();
void acceptConnect(int serverSock);
void receiveDataFromSocket(int socket);
void sendDataOverSocket(int clientSock);
void createServerSocket() {
int serverSockFd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
std::string address = "fd53:7cb8:383:5::73";
int port = 42519;
if (serverSockFd < 0)
{
printf("Create Server socket fail");
return;
}
struct sockaddr_in6 serverAddress;
(void)memset(&serverAddress, 0, sizeof(sockaddr_in6));
serverAddress.sin6_family = AF_INET6;
serverAddress.sin6_port = htons(port);
int result = inet_pton(AF_INET6, address.c_str(), &serverAddress.sin6_addr);
if (result <= 0)
{
printf("inet_pton() failed portnumber: %d, address: %s \n", port, address.c_str());
return;
}
// setting socket options
int flag = 1;
if(setsockopt(serverSockFd,IPPROTO_TCP,TCP_QUICKACK ,(char *)&flag,sizeof(flag)) == -1)
{
printf("setsockopt TCP_QUICKACK failed for server socket on address %s \n", address.c_str());
}
if(setsockopt(serverSockFd,IPPROTO_TCP,TCP_CORK,(char *)&flag,sizeof(flag)) == -1)
{
printf("setsockopt TCP_CORK failed for server socket on address %s \n", address.c_str());
}
if(setsockopt(serverSockFd,IPPROTO_TCP,TCP_NODELAY,(char *)&flag,sizeof(flag)) == -1)
{
printf("setsockopt TCP_NODELAY failed for server socket on address %s \n", address.c_str());
}
result = bind(serverSockFd, (struct sockaddr*)&serverAddress, sizeof(sockaddr_in6));
if (result != 0)
{
printf("bind() failed portnumber: %d, address: %s \n", port, address.c_str());
return ;
}
result = listen(serverSockFd, 10);
if (result != 0) {
printf("listen() failed portnumber: %d, address: %s \n", port, address.c_str());
return ;
}
acceptConnect(serverSockFd);
}
void acceptConnect(int serverSock)
{
struct sockaddr_in6 clientAddress;
socklen_t len = sizeof(sockaddr_in6);
memset(&clientAddress, 0, sizeof(sockaddr_in6));
const int clientSocket = accept(serverSock, (struct sockaddr*)&clientAddress, &len);
if(clientSocket >= 0) {
char str_addr[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &(clientAddress.sin6_addr),
str_addr, sizeof(str_addr));
printf("New connection from: %s:%d ...\n", str_addr, ntohs(clientAddress.sin6_port));
receiveDataFromSocket(clientSocket);
}
}
void receiveDataFromSocket(int socket)
{
int SOCKET_BUFFER_MAX_SIZE = 8*1024;
char buffer[SOCKET_BUFFER_MAX_SIZE];
memset(buffer, '\0', SOCKET_BUFFER_MAX_SIZE);
//Receive data from sock
while (true) {
int dataLen = recv(socket, buffer, SOCKET_BUFFER_MAX_SIZE, 0);
printf("Receive data from socket: %d, msgLength = %d\n", socket, dataLen);
sendDataOverSocket(socket);
}
}
void sendDataOverSocket(int clientSock)
{
int dataLen = 4*1024 + 7;
char *buf = new char[dataLen];
memset(buf, 'a', 4*1024 + 7);
int ret;
ret = send(clientSock, buf, dataLen, 0);
if (ret <= 0) {
printf("ERROR Send message over socket");
return;
}
int error_code;
socklen_t error_code_size = sizeof(sockaddr_in6);
getsockopt(clientSock, SOL_SOCKET, SO_ERROR, &error_code, &error_code_size);
printf("Error code size: %d, error code: %d\n", error_code_size, error_code);
}