Я новичок в Socket Programming
, Я пытаюсь создать приложение, которое использует Sockets
для связи.
У меня есть сомнения в функции получения, потому что иногда она просто зависает recvfrom
функция.
я использую select
функция для опроса. Это работает, когда камера подключена, но если я удаляю камеру, она не показывает сообщение об ошибке.
Мой код для опроса:
FD_ZERO(&m_readFds);
FD_SET(Sock, &m_readFds);
m_timeInterval.tv_usec = 30; //30 Microseconds for Polling
m_socketLength = sizeof(m_cameraInfo);
m_lastBlockId = -1;
while (m_acquiringThreadStatus)
{
FD_CLR(Sock, &m_readFds);
FD_SET(Sock, &m_readFds);
m_receivingStatus = select(Sock + 1, &m_readFds, NULL, NULL, &m_timeInterval);
if (m_receivingStatus < 0)
{
std::cout << "No Data to Receive"<<std::endl;
}
else
{
if ((m_receivedBytes = recvfrom(Sock, m_packetBuffer, RECEIVING_BUFFER_SIZE, 0, (struct sockaddr*)&m_cameraInfo, &m_socketLength)) == SOCKET_ERROR)
{
std::cout << "ERROR" << std::endl;
}
else
{
std::cout<<"Data Received"<<std::endl;
}
}
}
Еще один вопрос заключается в том, что, когда я постоянно печатаю Data Received
Заявление через некоторое время остановится. Так как я могу увеличить размер сокета Receiving Buffer
,
Заранее спасибо
редактировать
SOCKET m_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(m_sock == INVALID_SOCKET)
{
// Error
}
else
{
//In the else part bind the socket
}
Если вы читаете select()
документацию, вы увидите, что select()
возвращает -1 при ошибке, 0 при тайм-ауте и> 0 при запрошенных событиях. Однако это не то, как вы относитесь к возвращаемому значению. Вы рассматриваете -1 как тайм-аут и> = 0 как события данных. Итак, вы в конечном итоге recvfrom()
когда нет ничего доступного для чтения. Если сокет находится в режиме блокировки (режим по умолчанию), recvfrom()
будет блокировать вызывающий поток, пока данные не станут фактически доступными.
Попробуйте это вместо этого:
m_lastBlockId = -1;
while (m_acquiringThreadStatus)
{
FD_ZERO(&m_readFds);
FD_SET(Sock, &m_readFds);
m_timeInterval.tv_sec = 0;
m_timeInterval.tv_usec = 30; //30 Microseconds for Polling
m_receivingStatus = select(Sock + 1, &m_readFds, NULL, NULL, &m_timeInterval);
if (m_receivingStatus == SOCKET_ERROR)
{
std::cout << "ERROR" << std::endl;
break;
}
if (m_receivingStatus == 0)
{
std::cout << "No Data to Receive" << std::endl;
continue;
}
m_socketLength = sizeof(m_cameraInfo);
if ((m_receivedBytes = recvfrom(Sock, m_packetBuffer, RECEIVING_BUFFER_SIZE, 0, (struct sockaddr*)&m_cameraInfo, &m_socketLength)) == SOCKET_ERROR)
{
std::cout << "ERROR" << std::endl;
break;
}
std::cout << "Data Received" << std::endl;
}
Что касается размера приемного буфера сокета, вы можете установить его через setsockopt()
с использованием SO_RCVBUF
вариант, например:
int bufsize = ...;
setsockopt(Sock, SOL_SOCKET, SO_RCVBUF, (char*)&bufsize, sizeof(bufsize));
Других решений пока нет …