java udp 缓冲区_为什么特定的UDP消息总是低于特定的缓冲区大小?
3個不同的消息以不同的速率發(fā)送到同一個端口:
消息大小(字節(jié))每個傳輸速度發(fā)送
High23210 ms100Hz
Medium14820ms50Hz
低2060 ms16.6Hz
我每 ~ 6 ms 只能處理一條消息 .
單線程 . 阻止閱讀 .
一種奇怪的情況正在發(fā)生,我沒有解釋 .
當(dāng)我將接收緩沖區(qū)設(shè)置為 4,799 字節(jié)時,我的所有 low speed messages 都被刪除了 .
我看到可能有一兩個被處理,然后什么都沒有 .
當(dāng)我將接收緩沖區(qū)設(shè)置為 4,800 (或更高!)時,似乎所有低速消息都開始處理 . 我看到大約每秒16/17 .
這一點一直被觀察到 . 發(fā)送數(shù)據(jù)包的應(yīng)用程序始終在接收應(yīng)用程序之前啟動 . 創(chuàng)建套接字后,在開始處理之前,接收應(yīng)用程序總是有很長的延遲 . 因此,處理開始時緩沖區(qū)始終為滿,并且每次測試發(fā)生時它都不是相同的起始緩沖區(qū) . 這是因為套接字是在發(fā)送方已經(jīng)發(fā)送消息之后創(chuàng)建的,因此接收方可能會在發(fā)送周期的中間開始監(jiān)聽 .
Why does increasing the received buffer size a single byte, cause a huge change in low speed message processing?
我構(gòu)建了一個表來更好地可視化預(yù)期的處理:
由于其中一些消息得到處理,因此可能會將更多消息放入隊列而不是丟棄 .
盡管如此,我希望 4,799 字節(jié)緩沖區(qū)的行為與 4,800 字節(jié)相同 .
然而,這不是我所觀察到的 .
我認(rèn)為這個問題與低速消息與其他兩條消息同時發(fā)送的事實有關(guān) . 它總是在高/中速信息之后接收 . (已通過wireshark確認(rèn)) .
例如,假設(shè)緩沖區(qū)開始時為空,很明顯低速消息需要比其他消息排隊更長 .
*每6ms 1條消息大約每30ms發(fā)送5條消息 .
這仍然不能解釋緩沖區(qū)大小 .
我們正在運行VxWorks,并使用他們的sockLib,它是Berkeley套接字的一個實現(xiàn) . 這是我們的套接字創(chuàng)建的代碼片段:
SOCKET_BUFFER_SIZE 是我正在改變的 .
struct sockaddr_in tSocketAddress; // Socket address
int nSocketAddressSize = sizeof(struct sockaddr_in); // Size of socket address structure
int nSocketOption = 0;
// Already created
if (*ptParameters->m_pnIDReference != 0)
return FALSE;
// Create UDP socket
if ((*ptParameters->m_pnIDReference = socket(AF_INET, SOCK_DGRAM, 0)) == ERROR)
{
// Error
CreateSocketMessage(ptParameters, "CreateSocket: Socket create failed with error.");
// Not successful
return FALSE;
}
// Valid local address
if (ptParameters->m_szLocalIPAddress != SOCKET_ADDRESS_NONE_STRING && ptParameters->m_usLocalPort != 0)
{
// Set up the local parameters/port
bzero((char*)&tSocketAddress, nSocketAddressSize);
tSocketAddress.sin_len = (u_char)nSocketAddressSize;
tSocketAddress.sin_family = AF_INET;
tSocketAddress.sin_port = htons(ptParameters->m_usLocalPort);
// Check for any address
if (strcmp(ptParameters->m_szLocalIPAddress, SOCKET_ADDRESS_ANY_STRING) == 0)
tSocketAddress.sin_addr.s_addr = htonl(INADDR_ANY);
else
{
// Convert IP address for binding
if ((tSocketAddress.sin_addr.s_addr = inet_addr(ptParameters->m_szLocalIPAddress)) == ERROR)
{
// Error
CreateSocketMessage(ptParameters, "Unknown IP address.");
// Cleanup socket
close(*ptParameters->m_pnIDReference);
*ptParameters->m_pnIDReference = ERROR;
// Not successful
return FALSE;
}
}
// Bind the socket to the local address
if (bind(*ptParameters->m_pnIDReference, (struct sockaddr *)&tSocketAddress, nSocketAddressSize) == ERROR)
{
// Error
CreateSocketMessage(ptParameters, "Socket bind failed.");
// Cleanup socket
close(*ptParameters->m_pnIDReference);
*ptParameters->m_pnIDReference = ERROR;
// Not successful
return FALSE;
}
}
// Receive socket
if (ptParameters->m_eType == SOCKTYPE_RECEIVE || ptParameters->m_eType == SOCKTYPE_RECEIVE_AND_TRANSMIT)
{
// Set the receive buffer size
nSocketOption = SOCKET_BUFFER_SIZE;
if (setsockopt(*ptParameters->m_pnIDReference, SOL_SOCKET, SO_RCVBUF, (char *)&nSocketOption, sizeof(nSocketOption)) == ERROR)
{
// Error
CreateSocketMessage(ptParameters, "Socket buffer size set failed.");
// Cleanup socket
close(*ptParameters->m_pnIDReference);
*ptParameters->m_pnIDReference = ERROR;
// Not successful
return FALSE;
}
}
并且套接字接收在無限循環(huán)中被調(diào)用:
*緩沖區(qū)大小肯定足夠大
int SocketReceive(int nSocketIndex, char *pBuffer, int nBufferLength)
{
int nBytesReceived = 0;
char szError[256];
// Invalid index or socket
if (nSocketIndex < 0 || nSocketIndex >= SOCKET_COUNT || g_pnSocketIDs[nSocketIndex] == 0)
{
sprintf(szError,"SocketReceive: Invalid socket (%d) or ID (%d)", nSocketIndex, g_pnSocketIDs[nSocketIndex]);
perror(szError);
return -1;
}
// Invalid buffer length
if (nBufferLength == 0)
{
perror("SocketReceive: zero buffer length");
return 0;
}
// Send data
nBytesReceived = recv(g_pnSocketIDs[nSocketIndex], pBuffer, nBufferLength, 0);
// Error in receiving
if (nBytesReceived == ERROR)
{
// Create error string
sprintf(szError, "SocketReceive: Data Receive Failure: ", errno);
// Set error message
perror(szError);
// Return error
return ERROR;
}
// Bytes received
return nBytesReceived;
}
Any clues on why increasing the buffer size to 4,800 results in successful and consistent reading of low speed messages?
總結(jié)
以上是生活随笔為你收集整理的java udp 缓冲区_为什么特定的UDP消息总是低于特定的缓冲区大小?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: opencv java match_Op
- 下一篇: java 管理对象是什么_Java工程师
