-
February 15th, 2013, 11:24 PM
#1
[RESOLVED] Winsock UDP slows down to a stall.
I am the designated coder for my college's engineering club's robot team and our goal is to pass data from one laptop to another via ad hoc wifi. (We need quick updates, not through-put, and not ACK)
The code below works great on the localhost, but when I take the client app to another PC (Windows 7 32bit w/Visual Studio 2012) communication quickly begins to slow down into a near stall. The client program only responds about every four seconds (or more). The real oddity is after a few minutes two-way communication begins again briefly only to stall once more.
I am hoping someone will take a look and see what I am missing.
Info:
The code is in a form inside a 25ms timer and the data buffers are shown in labels. There is no extra code.
WireShark shows the server sending UDP packets, and the client sending UDP packets about four to eight seconds.
I tired changing the buffers, the timeout, when WSACleanup() is called... my knowledge in this area is limited.
The Server:
Code:
#define DEFAULT_PORT 12400
timeval send_timeout = {0, 0};
timeval recv_timeout = {0, 20000};
char *ip_address= NULL;
unsigned short port=DEFAULT_PORT;
int retval;
int fromlen;
struct sockaddr_in local, from;
WSADATA wsaData;
SOCKET listen_socket, conn_socket;
signed char select_return;
unsigned char socket_in_data[64] = {};
unsigned char socket_out_data[64] = {};
unsigned char usb_in_data[64];
char recv_buf[64] = {};
char send_buf[64] = {};
unsigned char socket_status;
unsigned char socket_send_status;
unsigned char socket_receive_status;
char retval_recv = 0;
char retval_send = 0;
socket_status = 0;
socket_send_status = 0;
socket_receive_status = 0;
while(1)
{
// Request Winsock version 2.2
if ((retval = WSAStartup(0x202, &wsaData)) != 0)
{
// error - WSAStartup()
break;
}
local.sin_family = AF_INET;
local.sin_addr.s_addr = (!ip_address) ? INADDR_ANY:inet_addr(ip_address);
// Port MUST be in Network Byte Order
local.sin_port = htons(port);
listen_socket = socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
if (listen_socket == INVALID_SOCKET){
// eeror - socket() failed
break;
}
if (bind(listen_socket, (struct sockaddr*)&local, sizeof(local)) == SOCKET_ERROR)
{
//error - bind() failed with error
break;
}
fromlen =sizeof(from);
conn_socket = listen_socket;
int send_buf_size_int = 64;
const char* send_buf_size = (const char*)&send_buf_size_int;
setsockopt(conn_socket, SOL_SOCKET, SO_SNDBUF, send_buf_size, NULL);
fd_set read_mask;
FD_ZERO(&read_mask);
FD_SET(conn_socket, &read_mask);
select_return = select(conn_socket + 1, &read_mask, (fd_set *)0, (fd_set *)0, &recv_timeout);
if(select_return < 0)
{
// error - select functions returned -1 error value
socket_receive_status = 31;
}
else if(select_return == 0)
{
// error - select functions returned 0 timeout value
socket_receive_status = 32;
// break the select() loop when there is no more data to read
socket_create_flag = true;
}
else
{
retval_recv = recvfrom(conn_socket,recv_buf, 64, 0, (struct sockaddr *)&from, &fromlen);
if (retval_recv == SOCKET_ERROR)
{
//error - recv() failed
socket_receive_status = 33;
} else {
// recv successful, update data buffers
socket_receive_status = 37;
memcpy(&socket_in_data, &recv_buf, sizeof(recv_buf));
memcpy(&socket_out_data, &recv_buf, sizeof(recv_buf)); //temp
}
} //end select
///////
fd_set write_mask;
FD_ZERO(&write_mask);
FD_SET(conn_socket, &write_mask);
select_return = select(conn_socket + 1, (fd_set *)0, &write_mask, (fd_set *)0, &send_timeout);
if(select_return < 0)
{
// error - select function returned -1 error value
socket_send_status = 20;
}
else if(select_return == 0)
{
// error - select function returned 0 timeout value
socket_send_status = 21;
}
else
{
// send data
socket_send_status = 27;
const char* send_buf = (const char*)&socket_out_data;
retval_send = sendto(conn_socket, send_buf, 64, 0, (struct sockaddr *)&from, fromlen);
if (retval_send == SOCKET_ERROR)
{
//error send() failed
socket_send_status = 22;
}
} //end select
socket_status = 1;
break;
} // end while
// Update UI for status and errors
this->label_socket_status_codes->Text = socket_status + " - " + socket_send_status + " - " + socket_receive_status + " - " + WSAGetLastError();
closesocket(conn_socket);
WSACleanup();
The Client:
Code:
nsigned char display_counter;
#define DEFAULT_PORT 12400
timeval send_timeout = {0, 0};
timeval recv_timeout = {0, 20000};
char *ip_address= NULL;
unsigned short port=DEFAULT_PORT;
int retval;
int fromlen;
struct sockaddr_in local, from;
WSADATA wsaData;
//SOCKET listen_socket, msgsock;
signed char select_return;
//client
char *server_name= "192.168.0.100";
struct sockaddr_in server;
struct hostent *hp;
SOCKET conn_socket;
unsigned int addr;
//client
unsigned char socket_in_data[64] = {};
unsigned char socket_out_data[64] = {};
unsigned char usb_in_data[64];
char recv_buf[64] = {};
char send_buf[64] = {};
unsigned char socket_status;
unsigned char socket_send_status;
unsigned char socket_receive_status;
display_counter++;
socket_out_data[0] = display_counter;
while(1) {
if ((retval = WSAStartup(0x202, &wsaData)) != 0)
{
//error - failed to startup
socket_status = 2;
break;
}
// Attempt to detect if we should call gethostbyname() or gethostbyaddr()
if (isalpha(server_name[0]))
{ // server address is a name
hp = gethostbyname(server_name);
}
else
{ // Convert nnn.nnn address to a usable one
addr = inet_addr(server_name);
hp = gethostbyaddr((char *)&addr, 4, AF_INET);
}
if (hp == NULL )
{
//error - cannot resolve address
socket_status = 3;
}
// Copy the resolved information into the sockaddr_in structure
memset(&server, 0, sizeof(server));
memcpy(&(server.sin_addr), hp->h_addr, hp->h_length);
server.sin_family = hp->h_addrtype;
server.sin_port = htons(port);
// Open a socket
conn_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (conn_socket <0 )
{
// error - opening socket
socket_status = 4;
}
if (connect(conn_socket, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
{
// error - connect failed
socket_status = 5;
}
int send_buf_size_int = 64;
const char* send_buf_size = (const char*)&send_buf_size_int;
//setsockopt(s, SOL_SOCKET, SO_RCVBUF, tete, NULL);
setsockopt(conn_socket, SOL_SOCKET, SO_SNDBUF, send_buf_size, NULL);
fd_set write_mask;
FD_ZERO(&write_mask);
FD_SET(conn_socket, &write_mask);
select_return = select(conn_socket + 1, (fd_set *)0, &write_mask, (fd_set *)0, &send_timeout);
if(select_return < 0)
{
// error - select function returned -1 error value
socket_send_status = 20;
}
else if(select_return == 0)
{
// error - select function returned 0 timeout value
socket_send_status = 21;
}
else
{
socket_send_status = 27;
const char* send_buf = (const char*)&socket_out_data;
select_return = send(conn_socket, send_buf, 64, 0);
if (select_return == SOCKET_ERROR)
{
//error send() failed
socket_send_status = 22;
}
} //end select
//////////
fd_set read_mask;
FD_ZERO(&read_mask);
FD_SET(conn_socket, &read_mask);
select_return = select(conn_socket + 1, &read_mask, (fd_set *)0, (fd_set *)0, &recv_timeout);
if(select_return < 0)
{
// error - select functions returned -1 error value
socket_receive_status = 31;
break;
}
else if(select_return == 0)
{
// error - select functions returned 0 timeout value
socket_receive_status = 32;
}
else
{
retval = recv(conn_socket, recv_buf, 64, 0);
if (retval == SOCKET_ERROR)
{
//error - recv() failed
socket_receive_status = 33;
} else {
// recv successful, update data buffers
socket_receive_status = 37;
memcpy(&socket_in_data, &recv_buf, sizeof(recv_buf));
}
} //end select
socket_status = 1;
break;
} //end while
// Update UI for status and errors
this->label_socket_status_codes->Text = socket_status + " - " + socket_send_status + " - " + socket_receive_status + " - " + WSAGetLastError();
closesocket(conn_socket);
WSACleanup();
Thank you.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|