🔒 Locked
Asyncronous Socket Problem
Advertisement
Original Post
Hi, I have been having some trouble with my Asyncronous Winsock Client. I built a skeleton Windows Program and then added the asyncronous sockets to it. I set it up to display the FD_ messages using textout(). Everything appears to work fine, except when I try to recieve data. I built a regular blocking server that waits for a connection, then spams the client with a string. I have tested the server with a blocking client and it works fine. But, the Asyncronous client will not display the string. It recieves the FD_READ message once, and displays a blank line for the recieved data. The server continues to spam the client, but no more FD_READ is called. What could be wrong in that it displays a blank instead of the string? There is not a problem with the textout() part, it must have something to do with the communication.
Thanks in advance for any insight you might have to offer me. Here is some other information about the client which you might find helpful in answering this.
WSAStartup(version, &wsaData);
LPHOSTENT lpHostEntry;
SOCKADDR_IN saServer;
lpHostEntry = gethostbyname("localhost"); //Specifying server by its name (using localhost 127.0.0.1)
saServer.sin_family = AF_INET;
saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
saServer.sin_port = htons(8888); //Port Number
SOCKET ClientSocket = socket(AF_INET, SOCK_STREAM, 0); //the socket for the client
WSAAsyncSelect(ClientSocket, hwnd, WM_WSAASYNC, FD_WRITE | FD_CONNECT | FD_READ | FD_CLOSE);
connect(ClientSocket, (LPSOCKADDR)&saServer, sizeof(saServer));
case FD_READ:
{
bytes_read = recv(ClientSocket, buf, sizeof(buf), 0);
dbtext(buf); //my function to display stuff
dbtext("FD_Read"); //my function to display stuff
}
Is buf defined as a simple array of chars (not a dynamic array)?
---------------
#define TRUE 0
#define FALSE 1
//MUAHAHAHAHAAAA!
---------------
#define TRUE 0
#define FALSE 1
//MUAHAHAHAHAAAA!
Hmmm... Sorry, I dunno what the problem is then
If it would help, I can post some code from my chat app.
---------------
#define TRUE 0
#define FALSE 1
//MUAHAHAHAHAAAA!
---------------
#define TRUE 0
#define FALSE 1
//MUAHAHAHAHAAAA!
Hrmm I tried it earlier and figured out that I needed to initialize it to 0, but it still didnt seem to work. I will try again though and post in a couple hours. Would having my entire source code help? I could post the main.cpp or send you the whole project.
Thanks for taking the time to help me with this, ive been struggling with this for a long time.
Thanks for taking the time to help me with this, ive been struggling with this for a long time.
Ozmo,
After the call to recv(), what is being return from that function (-1, 0, n bytes?)
Dire Wolf
www.digitalfiends.com
After the call to recv(), what is being return from that function (-1, 0, n bytes?)
Dire Wolf
www.digitalfiends.com
Hrmmm well bytes_recieved doesnt return anything...
I made it so that it would only display if it was over 0 and it doesnt. So recv() isnt returning anything.... what could be the problem there? Im going to post my main.cpp source code, cuase there must be something.
Uhhhhh........ Forget the quantinum torpedoes! Full speed ahead!
I made it so that it would only display if it was over 0 and it doesnt. So recv() isnt returning anything.... what could be the problem there? Im going to post my main.cpp source code, cuase there must be something.
Uhhhhh........ Forget the quantinum torpedoes! Full speed ahead!
Here we go...good luck... i took out the while that you gave me cause it didnt do anything, but here is the code.
// Client Test
//
// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN // just say no to MFC, NO!
#define WM_WSAASYNC (WM_USER +5)
#include <windows.h> // include all the windows headers
#include <windowsx.h> // include useful macros
#include "resources.h"
#include <winsock2.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <iostream.h>
// DEFINES ////////////////////////////////////////////////
// GLOBALS ////////////////////////////////////////////////
SOCKET ClientSocket = socket(AF_INET, SOCK_STREAM, 0);
char data[1024];
char buf[1024];
int bytes_read = 0;
int textlocation = 5;
int q = 1;
int i = 0;
WNDCLASSEX winclass; // this will hold the class we create
HWND hwnd; // generic window handle
MSG msg; // generic message
//Winsock Setup
WORD version = MAKEWORD(2,0); //***?Right Version for what I am doing??***
WSADATA wsaData;
// FUNCTIONS //////////////////////////////////////////////
void dbtext(char textstr[]) //Debug Text Out, should add logging to file
{
HDC gdc = GetDC(hwnd);
SetTextColor(gdc, RGB(200,0,0));
SetBkColor (gdc, RGB(0,0,0));
TextOut(gdc,0,textlocation,textstr,strlen(textstr));
ReleaseDC(hwnd, gdc);
textlocation = textlocation + 15;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
// this is the main message handler of the system
PAINTSTRUCT ps; // used in WM_PAINT
HDC hdc; // handle to a device context
// what is the message
switch(msg)
{
case WM_CREATE:
{
// do initialization stuff here
// return success
dbtext( "WM_Create");
return(0);
} break;
case WM_WSAASYNC:
{
switch (WSAGETSELECTEVENT(lparam))
{
case FD_READ:
{
recv(ClientSocket,buf,sizeof(buf),0);
dbtext(buf);
dbtext("FD_Read");
} break;
case FD_WRITE: //used for file transfers, don''t use
{
dbtext("FD_Write");
} break;
case FD_CLOSE:
{
dbtext("FD_Close");
} break;
case FD_CONNECT:
{
dbtext("FD_Connect");
} break;
}
}
case WM_COMMAND:
{
switch(LOWORD(wparam))
{
case MENU_FILE_ID_STARTMUD:
{
WSAStartup(version, &wsaData);
//Store information about the server
LPHOSTENT lpHostEntry;
SOCKADDR_IN saServer;
lpHostEntry = gethostbyname("localhost"); //Specifying server by its name
saServer.sin_family = AF_INET;
saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
// ^ Address of the server being inserted into the address
saServer.sin_port = htons(8888); //Port Number
SOCKET ClientSocket = socket(AF_INET, SOCK_STREAM, 0);
WSAAsyncSelect(ClientSocket, hwnd, WM_WSAASYNC, FD_WRITE | FD_CONNECT | FD_READ | FD_CLOSE);
connect(ClientSocket, (LPSOCKADDR)&saServer, sizeof(saServer));
}break;
case MENU_FILE_ID_DISCONNECT:
{
dbtext("Disconnect");
}break;
case MENU_FILE_ID_EXIT:
{
PostQuitMessage(0); //Quit Program, should add in Winsock disconn too
}break;
case MENU_HELP_ID_HELP: //Help Section, *Under Construction*
{
MessageBox(hwnd, "Help?!?! I don''t get paid enough for this!", "Note to yerself: Help is for morons!", MB_OK | MB_ICONEXCLAMATION);
}break;
case MENU_HELP_ID_ABOUT: //About Section, *Under Construction*
{
MessageBox(hwnd, "This program is trying to connect to a server.", "About: Client", MB_OK | MB_ICONEXCLAMATION);
}break;
}
// return success
return(0);
} break;
case WM_PAINT:
{
// simply validate the window
hdc = BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
dbtext("Paint");
// return success
return(0);
} break;
case WM_DESTROY: //Triggered by closing window, quits, should add winsock disconn
{
// kill the application, this sends a WM_QUIT message
PostQuitMessage(0);
// return success
return(0);
} break;
default:break;
} // end switch
// process any messages that we didn''t take care of
return (DefWindowProc(hwnd, msg, wparam, lparam));
} // end WinProc
// WINMAIN ////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
// first fill in the window class stucture
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_APPICON));
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = "MainMenu";
winclass.lpszClassName = "WINCLASS1";
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// register the window class
if (!RegisterClassEx(&winclass))
return(0);
// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
"WINCLASS1", // class
"Client", // title
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0,0, // initial x,y
800,550, // initial width, height
NULL, // handle to parent
NULL, // handle to menu
hinstance,// instance of this application
NULL))) // extra creation parms
return(0);
// save main window handle
//main_window_handle = hwnd;
// enter main event loop, but this time we use PeekMessage()
// instead of GetMessage() to retrieve messages
while(TRUE)
{
// test if there is a message in queue, if so get it
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// test if this is a quit
if (msg.message == WM_QUIT)
break;
// translate any accelerator keys
TranslateMessage(&msg);
// send the message to the window proc
DispatchMessage(&msg);
} // end if
// main game processing goes here
} // end while
// return to Windows like this
return(msg.wParam);
} // end WinMain
///////////////////////////////////////////////////////////
// Client Test
//
// INCLUDES ///////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN // just say no to MFC, NO!
#define WM_WSAASYNC (WM_USER +5)
#include <windows.h> // include all the windows headers
#include <windowsx.h> // include useful macros
#include "resources.h"
#include <winsock2.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <iostream.h>
// DEFINES ////////////////////////////////////////////////
// GLOBALS ////////////////////////////////////////////////
SOCKET ClientSocket = socket(AF_INET, SOCK_STREAM, 0);
char data[1024];
char buf[1024];
int bytes_read = 0;
int textlocation = 5;
int q = 1;
int i = 0;
WNDCLASSEX winclass; // this will hold the class we create
HWND hwnd; // generic window handle
MSG msg; // generic message
//Winsock Setup
WORD version = MAKEWORD(2,0); //***?Right Version for what I am doing??***
WSADATA wsaData;
// FUNCTIONS //////////////////////////////////////////////
void dbtext(char textstr[]) //Debug Text Out, should add logging to file
{
HDC gdc = GetDC(hwnd);
SetTextColor(gdc, RGB(200,0,0));
SetBkColor (gdc, RGB(0,0,0));
TextOut(gdc,0,textlocation,textstr,strlen(textstr));
ReleaseDC(hwnd, gdc);
textlocation = textlocation + 15;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
// this is the main message handler of the system
PAINTSTRUCT ps; // used in WM_PAINT
HDC hdc; // handle to a device context
// what is the message
switch(msg)
{
case WM_CREATE:
{
// do initialization stuff here
// return success
dbtext( "WM_Create");
return(0);
} break;
case WM_WSAASYNC:
{
switch (WSAGETSELECTEVENT(lparam))
{
case FD_READ:
{
recv(ClientSocket,buf,sizeof(buf),0);
dbtext(buf);
dbtext("FD_Read");
} break;
case FD_WRITE: //used for file transfers, don''t use
{
dbtext("FD_Write");
} break;
case FD_CLOSE:
{
dbtext("FD_Close");
} break;
case FD_CONNECT:
{
dbtext("FD_Connect");
} break;
}
}
case WM_COMMAND:
{
switch(LOWORD(wparam))
{
case MENU_FILE_ID_STARTMUD:
{
WSAStartup(version, &wsaData);
//Store information about the server
LPHOSTENT lpHostEntry;
SOCKADDR_IN saServer;
lpHostEntry = gethostbyname("localhost"); //Specifying server by its name
saServer.sin_family = AF_INET;
saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
// ^ Address of the server being inserted into the address
saServer.sin_port = htons(8888); //Port Number
SOCKET ClientSocket = socket(AF_INET, SOCK_STREAM, 0);
WSAAsyncSelect(ClientSocket, hwnd, WM_WSAASYNC, FD_WRITE | FD_CONNECT | FD_READ | FD_CLOSE);
connect(ClientSocket, (LPSOCKADDR)&saServer, sizeof(saServer));
}break;
case MENU_FILE_ID_DISCONNECT:
{
dbtext("Disconnect");
}break;
case MENU_FILE_ID_EXIT:
{
PostQuitMessage(0); //Quit Program, should add in Winsock disconn too
}break;
case MENU_HELP_ID_HELP: //Help Section, *Under Construction*
{
MessageBox(hwnd, "Help?!?! I don''t get paid enough for this!", "Note to yerself: Help is for morons!", MB_OK | MB_ICONEXCLAMATION);
}break;
case MENU_HELP_ID_ABOUT: //About Section, *Under Construction*
{
MessageBox(hwnd, "This program is trying to connect to a server.", "About: Client", MB_OK | MB_ICONEXCLAMATION);
}break;
}
// return success
return(0);
} break;
case WM_PAINT:
{
// simply validate the window
hdc = BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
dbtext("Paint");
// return success
return(0);
} break;
case WM_DESTROY: //Triggered by closing window, quits, should add winsock disconn
{
// kill the application, this sends a WM_QUIT message
PostQuitMessage(0);
// return success
return(0);
} break;
default:break;
} // end switch
// process any messages that we didn''t take care of
return (DefWindowProc(hwnd, msg, wparam, lparam));
} // end WinProc
// WINMAIN ////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
// first fill in the window class stucture
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(hinstance, MAKEINTRESOURCE(IDI_APPICON));
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = "MainMenu";
winclass.lpszClassName = "WINCLASS1";
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// register the window class
if (!RegisterClassEx(&winclass))
return(0);
// create the window
if (!(hwnd = CreateWindowEx(NULL, // extended style
"WINCLASS1", // class
"Client", // title
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0,0, // initial x,y
800,550, // initial width, height
NULL, // handle to parent
NULL, // handle to menu
hinstance,// instance of this application
NULL))) // extra creation parms
return(0);
// save main window handle
//main_window_handle = hwnd;
// enter main event loop, but this time we use PeekMessage()
// instead of GetMessage() to retrieve messages
while(TRUE)
{
// test if there is a message in queue, if so get it
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// test if this is a quit
if (msg.message == WM_QUIT)
break;
// translate any accelerator keys
TranslateMessage(&msg);
// send the message to the window proc
DispatchMessage(&msg);
} // end if
// main game processing goes here
} // end while
// return to Windows like this
return(msg.wParam);
} // end WinMain
///////////////////////////////////////////////////////////
So, finaly I''ve registered here at gamedev! :-))
.
.
.
And you sould replace your ''send'' function with this one.
int tcp_send( int iSocket, char* pBuffer, int iBufferSize, int iTimeout )
{
struct tv timeout, timeout_master;
fd_set write_fd, write_fd_master;
int count, i = 0;
timeout_master.tv_sec = iTimeout;
timeout_master.tv_usec = 0;
FD_ZERO( &write_fd_master );
FD_SET( iSocket, &write_fd_master );
while( 1 )
{
write_fd = write_fd_master;
timeout = timeout_master;
switch( select( iSocket+1, 0, &write_fd, 0, (struct timeval*) &timeout ) )
{
case -1: return TCP_CONNECTION_LOST;
case 0: return TCP_TIMEOUT_WRITE;
default:
count = send( iSocket, pBuffer+i, iBufferSize-i, 0 );
if( count <= 0 ) return TCP_ERROR;
i += count;
if( i == iBufferSize ) return TCP_OK;
if( i > iBufferSize ) return TCP_ERROR;
}
}
}
.
.
.
And you sould replace your ''send'' function with this one.
int tcp_send( int iSocket, char* pBuffer, int iBufferSize, int iTimeout )
{
struct tv timeout, timeout_master;
fd_set write_fd, write_fd_master;
int count, i = 0;
timeout_master.tv_sec = iTimeout;
timeout_master.tv_usec = 0;
FD_ZERO( &write_fd_master );
FD_SET( iSocket, &write_fd_master );
while( 1 )
{
write_fd = write_fd_master;
timeout = timeout_master;
switch( select( iSocket+1, 0, &write_fd, 0, (struct timeval*) &timeout ) )
{
case -1: return TCP_CONNECTION_LOST;
case 0: return TCP_TIMEOUT_WRITE;
default:
count = send( iSocket, pBuffer+i, iBufferSize-i, 0 );
if( count <= 0 ) return TCP_ERROR;
i += count;
if( i == iBufferSize ) return TCP_OK;
if( i > iBufferSize ) return TCP_ERROR;
}
}
}
rmmm, didnt work.....I didn''t implement the send one, just the receive, but I have a few questions though.
1) Is struct tv defined in some header or did you make it? I made my own so that the program would compile but I do not know if it needs anything besides tv_sec and tv_usec defined as ints.
2) What should the return messages be defined as? I set TCP_OK to 1 and the rest to 0.
3) What does these do? Like what is FD_SET and FD_ZERO...
fd_set read_fd, read_fd_master;
FD_ZERO( &read_fd_master );
FD_SET( iSocket, &read_fd_master );
They look like something that should belong in this line.
WSAAsyncSelect(ClientSocket, hwnd, WM_WSAASYNC, FD_WRITE | FD_CONNECT | FD_READ | FD_CLOSE);
4) In tcp_recv, what should I set the timeout to?
5) Also I get this warning: main.cpp(67) : warning C4018: ''=='' : signed/unsigned mismatch
For this line:
FD_SET( iSocket, &read_fd_master );
I think thats all for now ^^
Thanks...
1) Is struct tv defined in some header or did you make it? I made my own so that the program would compile but I do not know if it needs anything besides tv_sec and tv_usec defined as ints.
2) What should the return messages be defined as? I set TCP_OK to 1 and the rest to 0.
3) What does these do? Like what is FD_SET and FD_ZERO...
fd_set read_fd, read_fd_master;
FD_ZERO( &read_fd_master );
FD_SET( iSocket, &read_fd_master );
They look like something that should belong in this line.
WSAAsyncSelect(ClientSocket, hwnd, WM_WSAASYNC, FD_WRITE | FD_CONNECT | FD_READ | FD_CLOSE);
4) In tcp_recv, what should I set the timeout to?
5) Also I get this warning: main.cpp(67) : warning C4018: ''=='' : signed/unsigned mismatch
For this line:
FD_SET( iSocket, &read_fd_master );
I think thats all for now ^^
Thanks...
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement