apakah mungkin untuk mengirim 2 paket TCP berturut-turut seperti yang terlihat pada gambar di sini:
Saat ini saya telah menyetel TCP_NODELAY ke true dan SO_SNDBUF ke 0. Saya juga memanggil send di program saya 2x. Inilah hasil yang saya peroleh:
Masalah utama di sini adalah penundaan ack yang menyebabkan kinerja jaringan lambat pada tangkapan layar ke-2.
Kode untuk servernya:
DWORD WINAPI ServerHandler(void *lp){
//The port you want the server to listen on
int host_port = 1852;
//Initialize socket support WINDOWS ONLY!
unsigned short wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 || ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ))
{
printf("Could not find useable sock dll %d\n",WSAGetLastError());
return 0;
}
//Initialize sockets and set any options
int hsock;
BOOL bOptVal = true;
int bOptLen = sizeof (BOOL);
int iResult = 0;
hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(hsock == INVALID_SOCKET)
{
printf("Error initializing socket %d\n",WSAGetLastError());
return 0;
}
iResult = setsockopt(hsock, SOL_SOCKET, SO_REUSEADDR, (char *) &bOptVal, bOptLen);
if (iResult == SOCKET_ERROR)
printf("setsockopt for SO_REUSEADDR failed with error: %d\n", WSAGetLastError());
else
printf("Set SO_REUSEADDR: ON\n");
iResult = setsockopt(hsock, SOL_SOCKET, SO_KEEPALIVE, (char *) &bOptVal, bOptLen);
if (iResult == SOCKET_ERROR)
printf("setsockopt for SO_KEEPALIVE failed with error: %d\n", WSAGetLastError());
else
printf("Set SO_KEEPALIVE: ON\n");
//Bind and listen
struct sockaddr_in my_addr;
my_addr.sin_family = AF_INET ;
my_addr.sin_port = htons(host_port);
memset(&(my_addr.sin_zero), 0, 8);
my_addr.sin_addr.s_addr = INADDR_ANY ;
if( bind( hsock, (struct sockaddr*)&my_addr, sizeof(my_addr)) == SOCKET_ERROR )
{
printf("Error binding to socket, make sure nothing else is listening on this port %d\n",WSAGetLastError());
closesocket(hsock);
return 0;
}
if( listen( hsock, MAXCONN) == SOCKET_ERROR )
{
printf("Error listening %d\n",WSAGetLastError());
closesocket(hsock);
return 0;
}
//Now lets to the server stuff
int* csock;
sockaddr_in sadr;
int addr_size = sizeof(SOCKADDR);
printf("waiting for a connection\n");
while(true)
{
csock = (int*)malloc(sizeof(int));
if((*csock = accept( hsock, (SOCKADDR*)&sadr, &addr_size))!= INVALID_SOCKET )
{
printf("Received connection from %s, %u @ socket %d\n", inet_ntoa(sadr.sin_addr), sadr.sin_port, *csock);
BOOL bOptVal = true;
int iResult = setsockopt(*csock, SOL_SOCKET, TCP_NODELAY, (char *) &bOptVal, sizeof(bOptVal));
if (iResult == SOCKET_ERROR)
printf("setsockopt for TCP_NODELAY failed with error: %d\n", WSAGetLastError());
else
printf("Set TCP_NODELAY: TRUE\n");
int sendBuf = 0;
iResult = setsockopt(*csock, SOL_SOCKET, SO_SNDBUF, (char *) &sendBuf, sizeof(sendBuf));
if (iResult == SOCKET_ERROR)
printf("setsockopt for SO_SNDBUF failed with error: %d\n", WSAGetLastError());
else
printf("Setsockopt for SO_SNDBUF set to 0\n");
CreateThread(0,0,&SocketHandler, (void*)csock , 0,0);
}
else
{
printf("Error accepting %d\n",WSAGetLastError());
}
}
WSACleanup();
}
Kode yang saya gunakan untuk mengirim data:
int send_TCP_2(int cs, char responseLength[], char data[], int respond_length, int data_length)
{
int size = respond_length + data_length;
int index = 0;
// combined 10 byte response with data as 1 packet
std::vector<char> packet(size);
for(int i=0; i<respond_length; i++)
{
packet[index] = responseLength[i];
index++;
}
for(int i=0; i<data_length; i++)
{
packet[index] = data[i];
index++;
}
int status;
char *data_ptr = &packet[0];
while(size > 0)
{
status = send(cs, data_ptr, size, 0);
if(status > 0)
{
data_ptr += status;
size -= status;
}
else if (status == SOCKET_ERROR)
{
int error_code = WSAGetLastError();
printf("send_TCP_2 failed with error code: %d\n", error_code);
return 0; // send failed
}
}
return 1; // send successful
}
Saya telah melampirkan tangkapan layar ketika saya tidak menonaktifkan Nagle dan tidak menyentuh SO_SNDBUF.
TCP_NODELAY
seharusnya cukup di sini. - person Nikolai Fetissov   schedule 15.03.2012man 7 socket
di Linux: `SO_SNDBUF Mengatur atau mendapatkan buffer pengiriman soket maksimum dalam byte. Kernel menggandakan nilai ini (untuk memberikan ruang untuk overhead pembukuan) ketika diatur menggunakan setockopt(2), dan nilai ganda ini dikembalikan oleh getockopt(2). Nilai default ditetapkan oleh file /proc/sys/net/core/wmem_default dan nilai maksimum yang diizinkan ditetapkan oleh file /proc/sys/net/core/wmem_max. Nilai minimum (dua kali lipat) untuk opsi ini adalah 2048. - person Kaz   schedule 15.03.2012SO_SNDBUF
ke 0 mungkin tidak berfungsi di semua tempat. Apakah itu didokumentasikan pada OS yang Anda gunakan? - person Kaz   schedule 15.03.2012