-
Select(); server help!
Ok, so I've done a select server before, but i've lost my code and I need the same flexability for a new app i'm making. There are a couple problems. When I run the program, the sockets seam to bind fine and the code tells me it is listening, however it doesnt show up in netstat on xp or vista... But I have a couple client/server dos proggies that work that don't show up either. Anyone know why? I am no good at debugging so things like this always help if they work.
Second, (this didnt used to happen) but after i run the app, i click "ID_START_SERVER" and it goes into this:
Code:
case ID_START_SERVER:
if(ServRunning==TRUE)
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"The Server is already Started.");
break;
}
ServRunning=TRUE;
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Searching for Connections...");
MSG msg; // Message structure.
SOCKET AcceptSocket;
AcceptSocket=SOCKET_ERROR;
while(ServRunning==TRUE)
{
if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE))
{
DispatchMessage(&msg);
TranslateMessage(&msg);
}
else
{
///////////////////////////////
//do busy work here
////////////////////////////////
// request occurs, call the accept function to handle the request.
AcceptSocket = accept(m_socket, NULL, NULL);
if(AcceptSocket ==SOCKET_ERROR)
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)".");
}
else
{
m_socket = AcceptSocket;
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Client Connected!");
}
} //else
} //while(servrunning==true);
break; //id_start_server
basically i have the peakmessage /translatemsg so I can get the window to respond so i can stop it. With the code I have in there for accepting a new connection, it won't respond. I had some other code in there that worked better, but it still wouldn't accept a connection.
Third, the code doesn't work anyway. Won't accept a connection from a client(from what little I have tested) and i'm assuming it has to do with how i'm handling the winsock programming. I can post the rest of the code if necessary. There isn't too much more.
-
Quote:
Originally Posted by
klipseracer
Code:
AcceptSocket = accept(m_socket, NULL, NULL);
if(AcceptSocket ==SOCKET_ERROR)
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)".");
}
else
{
m_socket = AcceptSocket;
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Client Connected!");
}
You are listening on m_socket, but you overwrite it when a client connects. That can't be right.
Also, I see no call to bind() or listen() anywhere. You said you call them, but let's see the code that does it.
-
I use VC++ 2005 and i have a form for the GUI, its dialog based with a LIST that I output to.
The code i'm showing here actually isn't the same code with the select() but I can post it if you want. I just am trying to get my GUI working with the winsock code first, and the select() part I can figure out.
Code:
#include <windows.h>
#include "resource.h"
//Globals
BOOL ServRunning = FALSE;
WSADATA wsaData;
int wsaerr;
int port=4005;
//Create a SOCKET object called m_socket.
SOCKET m_socket;
//protos
int StartSock(HWND hwnd);
//Macros
// Using MAKEWORD macro, Winsock version request 2.2
WORD wVersionRequested = MAKEWORD(2, 2);
BOOL CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
switch(Message)
{
case WM_INITDIALOG:
// This is where we set up the dialog box, and initialise any default values
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Server Initializing...");
StartSock(hwnd);
break;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case ID_FILE_EXIT:
closesocket(m_socket);
WSACleanup();
ServRunning=FALSE;
EndDialog(hwnd,0);
break;
case ID_STOP_SERVER:
if(ServRunning==FALSE)
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"The Server is already stopped.");
break;
}
ServRunning=FALSE;
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Server Halted.");
break;
case ID_START_SERVER:
if(ServRunning==TRUE)
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"The Server is already Started.");
break;
}
ServRunning=TRUE;
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Searching for Connections...");
MSG msg; // Message structure.
SOCKET AcceptSocket;
AcceptSocket=SOCKET_ERROR;
while(ServRunning==TRUE)
{
if (PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE))
{
DispatchMessage(&msg);
TranslateMessage(&msg);
}
else
{
///////////////////////////////
//do busy work here
////////////////////////////////
// Create a temporary SOCKET object called AcceptSocket for accepting connections.
// Create a continuous loop that checks for connections requests. If a connection
// request occurs, call the accept function to handle the request.
AcceptSocket = accept(m_socket, NULL, NULL);
if(AcceptSocket ==SOCKET_ERROR)
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)".");
}
else
{
m_socket = AcceptSocket;
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Client Connected!");
ServRunning=FALSE; //I added this to stop the looping. Basically, I just want to get one client to connect first.
}
} //else
} //while(servrunning==true);
break; //id_start_server
} //switch(LOWORD)
break; //wm_command
case WM_CLOSE:
closesocket(m_socket);
WSACleanup();
ServRunning=FALSE;
EndDialog(hwnd, 0);
break;
default:
return FALSE;
}
return TRUE;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
return DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DlgProc);
}
/////////////////////
//Functions
///////
int StartSock(HWND hwnd)
{
/////////////////////////////////////
// Windows Socket startup
/////////////////////////////////
wsaerr = WSAStartup(wVersionRequested, &wsaData);
if (wsaerr != 0)
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Winsock .dll Not found!");
EndDialog(hwnd,0);
}
////////////
//Create a Socket
////////
// Call the socket function and return its value to the m_socket variable.
// For this application, use the Internet address family, streaming sockets, and
// the TCP/IP protocol.
// using AF_INET family, TCP socket type and protocol of the AF_INET - IPv4
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
/*use setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse_addr,
sizeof(reuse_addr))*///in the future to reuse socket from time_wait issue
//setnonblocking(m_socket);
// Check for errors to ensure that the socket is a valid socket.
if (m_socket == INVALID_SOCKET)
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Error at socket:");
WSACleanup();
}
else
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Socket Created!");
}
////////////////bind//////////////////////////////
// Create a sockaddr_in object and set its values.
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_port = port;
// Call the bind function, passing the created socket and the sockaddr_in structure as parameters.
// Check for general errors.
if (bind(m_socket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR)
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Bind Failed!");
closesocket(m_socket);
}
else
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Socket Bound OK!");
}
// Call the listen function, passing the created socket and the maximum number of allowed
// connections to accept as parameters. Check for general errors.
if (listen(m_socket, 1) == SOCKET_ERROR)
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Error listending!");
else
{
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Server is now listening for incomming connections!");
}
SendDlgItemMessage(hwnd,IDC_LIST1, LB_ADDSTRING,0,(LPARAM)"Done....start the Server!");
return 0;
}
Here is resource.h:
Code:
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by SunServ.rc
//
#define IDD_MAIN 101
#define IDR_MENU1 102
#define IDC_LIST1 1001
#define ID_FILE_EXIT 40001
#define ID_SERVER_STARTSERVER 40002
#define ID_START_SERVER 40003
#define ID_SERVER_STOPSERVER 40004
#define ID_STOP_SERVER 40005
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40006
#define _APS_NEXT_CONTROL_VALUE 1002
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
Here is the SunServ.rc file:
Code:
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MAIN DIALOGEX 0, 0, 186, 94
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "SunServ"
MENU IDR_MENU1
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LISTBOX IDC_LIST1,7,7,172,80,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
IDD_MAIN, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 87
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU1 MENU
BEGIN
POPUP "File"
BEGIN
MENUITEM "Exit", ID_FILE_EXIT
END
POPUP "Server"
BEGIN
MENUITEM "Start Server", ID_START_SERVER
MENUITEM "Stop Server", ID_STOP_SERVER
END
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
If there is a better way to code all this while keeping the simple dialog app, let me know. I would use a real window, but I couldn't figure out how to get a log window working right that displays 'debug' info.
Here is where I got the select() code from:
http://www.tenouk.com/Winsock/Winsock2example3.html
-
I've found that if I comment out
Code:
AcceptSocket = accept(m_socket, NULL, NULL);
the program doesn't hang, and it works like normal, but of course the connections aren't made.
EDIT:
Furthur research explains the non-blocking code I've been leaving out.
I added this:
Code:
ULONG NonBlock=1;
ioctlsocket(m_socket, FIONBIO, &NonBlock);
And it seams to loop nicely. Now, just to get it to actually function...
EDIT2: With this new code my client is able to connect. Now, I just need to straighten out the Select() portion of this.