📄 socket lib.cpp
字号:
//
// winSocket testbed application
// Ryan Lederman - ryan@winprog.org / http://ryan.ript.net/
// 01/21/2002 - 12:15 AM
// Notes: Make sure to link with wsock32.lib and libcmt.lib (for multithreading)
//
#include "stdafx.h"
#include "resource.h"
#include "winSocket.h"
#include "stdlib.h"
#include "process.h"
// Defines
#define MSGBOX_ERROR(x) MessageBox( GetForegroundWindow(), TEXT(x), "winSocket - ERROR", MB_OK | MB_ICONSTOP )
#define WM_WINSOCK (WM_USER+1)
#define WINTHREAD unsigned __stdcall
// Function declarations
BOOL CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
LRESULT OnConnect( HWND hWnd );
LRESULT OnCommand( HWND hWnd, WPARAM wParam, LPARAM lParam );
LRESULT OnWinsockEvent( HWND hWnd, WPARAM wParam, LPARAM lParam );
LRESULT OnSend( HWND hWnd );
LRESULT OnResetField( HWND hWnd, int ID );
void EnableEdits( HWND hWnd, BOOL bEnable );
void EditPrint( HWND hWnd, char *format, ... );
void EditAppendPrint( HWND hWnd, char *szOutput, ... );
void ToggleConnectedState( HWND hWnd, BOOL bConnected );
void DisableForConnect( HWND hWnd, BOOL bEnable );
void DoConnect( HWND hWnd );
WINTHREAD ConnectThread( void *pVoid );
// Global variables
winSocket m_Socket; // Our winSocket wrapper class
BOOL m_bConnected; // Boolean representing state of application
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
//
// Entry point for the application.
// Initializes the main window (dialog) and waits to exit
// When this function returns, the process is exited and
// control is returned to Windows
//
if( DialogBox( hInstance, (LPCSTR)IDD_MAIN, NULL, WndProc ) == -1 )
{
MSGBOX_ERROR( "Failed to initialize application!" );
return 1;
}
return 0;
}
BOOL CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
//
// Message procedure for our user interface
// All messages will pass through this function
//
switch( msg )
{
case WM_INITDIALOG:
if( m_Socket.Create() != ERR_SUCCESS ) // Create the socket
MSGBOX_ERROR( "Failed to create socket!" );
break;
case WM_CLOSE:
m_Socket.Close(); // Destroy the socket
EndDialog( hWnd, 0 );
PostQuitMessage( 0 );
break;
case WM_COMMAND: return OnCommand( hWnd, wParam, lParam );
case WM_WINSOCK: return OnWinsockEvent( hWnd, wParam, lParam );
}
return 0;
}
LRESULT OnWinsockEvent( HWND hWnd, WPARAM wParam, LPARAM lParam )
{
//
// WM_WINSOCK message handler. This function is executed when
// an event or error occurs on our non-blocking socket (m_Socket)
//
WORD wEvent = 0;
WORD wError = 0;
char szIncomingData[1024] = {0};
char szErrDisplay[1024] = {0};
char szLastError[ERR_MAXLENGTH+1] = {0};
int iLastError = 0;
wError = WSAGETSELECTERROR( lParam ); // Find out if any errors occurred.
if( wError )
{ // Some error DID occur, so find out what it was and display it
m_Socket.get_LastError( szLastError, &iLastError );
wsprintf( szErrDisplay, "A Winsock error occurred.\nDescription: %s\nError Number: %d", szLastError, iLastError );
MSGBOX_ERROR( szErrDisplay );
return 0;
}
wEvent = WSAGETSELECTEVENT( lParam ); // Get the event that occurred
switch( wEvent )
{
case FD_READ: // Data has arrived on the socket, append to received field
m_Socket.Receive( (SOCKET)wParam, szIncomingData, 1024 ); // Read data from socket
EditAppendPrint( hWnd, "%s\r\n", szIncomingData );
break;
case FD_CLOSE: // Connection was closed by remote side
ToggleConnectedState( hWnd, FALSE );
EnableEdits( hWnd, TRUE );
m_Socket.Close(); // Reset our socket object
break;
}
return 0;
}
LRESULT OnConnect( HWND hWnd )
{
//
// This function is executed when the connect/disconnect button
// is pressed, and performs the associated operation
//
UINT iThreadID = 0;
if( m_bConnected ) // We're already connected, do disconnect
{
m_Socket.Close(); // Close socket and reset object
ToggleConnectedState( hWnd, FALSE );
EnableEdits( hWnd, TRUE );
SetFocus( GetDlgItem( hWnd, IDC_HOST ) );
return 0;
}
// Otherwise, let's connect. Spawn the connection thread which handles remote connection
_beginthreadex( NULL, 0, ConnectThread, (void*)hWnd, 0, &iThreadID );
return 0;
}
WINTHREAD ConnectThread( void *pVoid )
{
//
// This thread is spawned when a connection needs to be made.
// if the Connect() call is not in a seperate thread from the message loop,
// the user interface will lock up while Connect() executes.
//
DoConnect( (HWND)pVoid );
_endthreadex( 0 );
return 0;
}
void DoConnect( HWND hWnd )
{
//
// This function is executed by the ConnectThread.
// it disables parts of the user interface while the connection is processed
//
char szHost[512] = {0};
char szPort[512] = {0};
char szLastError[ERR_MAXLENGTH+1] = {0};
int iLastError = 0;
EnableEdits( hWnd, FALSE ); // Disable host and port fields
SetWindowText( hWnd, "winSocket - Connecting..." ); // Let user know the app is working
DisableForConnect( hWnd, FALSE );
GetDlgItemText( hWnd, IDC_HOST, szHost, 512 );
GetDlgItemText( hWnd, IDC_PORT, szPort, 512 ); // Yeah, I know you don't need 512 :P
if( strlen( szHost ) == 0 || strlen( szPort ) == 0 )
{
// Bad param(s)!
EnableEdits( hWnd, TRUE );
MSGBOX_ERROR( "Please fill in the host and port fields before connecting." );
return;
}
if( m_Socket.Create() != ERR_SUCCESS )
{
MSGBOX_ERROR( "Failed to create socket!" );
return;
}
if( m_Socket.Connect( szHost, atoi( szPort ) ) != ERR_SUCCESS ) // Connect to remote host
{
EnableEdits( hWnd, TRUE ); // It failed, re-enable edit boxes
ToggleConnectedState( hWnd, FALSE ); // Reset application to disconnected state
DisableForConnect( hWnd, TRUE );
m_Socket.get_LastError( szLastError, &iLastError ); // Get error information from socket
EditPrint( hWnd, "Failed to connect to [%s : %d]!\r\nError: %s - %d", szHost, atoi( szPort ), szLastError, iLastError );
return;
}
// Connected!
DisableForConnect( hWnd, TRUE );
ToggleConnectedState( hWnd, TRUE );
SetFocus( GetDlgItem( hWnd, IDC_TOSEND ) );
if( m_Socket.asyncSelect( hWnd, WM_WINSOCK, FD_READ | FD_CLOSE ) != ERR_SUCCESS ) // Async0rize our socket
MSGBOX_ERROR( "Failed to set socket to non-blocking mode!" );
}
LRESULT OnSend( HWND hWnd )
{
//
// This function is executed when the user presses the Send button
// while connected to a remote host.
// Sends whatever data is in the send field to the remote site
//
char szOutgoingData[2048] = {0};
GetDlgItemText( hWnd, IDC_TOSEND, szOutgoingData, 2048 );
if( strlen( szOutgoingData ) <= 0 )
{
MSGBOX_ERROR( "No data to send!" );
return 0;
}
m_Socket.Send( szOutgoingData, strlen( szOutgoingData ) ); // Send the data to the remote host
return 0;
}
LRESULT OnCommand( HWND hWnd, WPARAM wParam, LPARAM lParam )
{
//
// This is the WM_COMMAND message handler.
// it is executed when the user presses one of the buttons
// on the user interface
//
switch( LOWORD( wParam ) )
{
case IDC_CONNECT: return OnConnect( hWnd );
case IDC_SEND: return OnSend( hWnd );
case IDC_RESETRECEIVE: return OnResetField( hWnd, IDC_RECEIVED );
case IDC_RESETSEND: return OnResetField( hWnd, IDC_TOSEND );
}
return 0;
}
LRESULT OnResetField( HWND hWnd, int ID )
{
SetDlgItemText( hWnd, ID, "" );
return 0;
}
void ToggleConnectedState( HWND hWnd, BOOL bConnected )
{
//
// This function toggles the user interface between
// connected and disconnected states
//
char szCaption[1024] = {0};
char szHost[512] = {0};
int iRemotePort = 0;
switch( bConnected )
{
case TRUE:
SetDlgItemText( hWnd, IDC_CONNECT, "&Disconnect" );
EnableWindow( GetDlgItem( hWnd, IDC_SEND ), TRUE );
m_Socket.get_RemoteHost( szHost, 512 ); // Get remote host and IP address from socket
m_Socket.get_RemotePort( &iRemotePort );
wsprintf( szCaption, "winSocket - %s : %d", szHost, iRemotePort );
SetWindowText( hWnd, szCaption );
break;
case FALSE:
SetDlgItemText( hWnd, IDC_CONNECT, "&Connect" );
EnableWindow( GetDlgItem( hWnd, IDC_SEND ), FALSE );
SetWindowText( hWnd, "winSocket test application" );
break;
}
m_bConnected = bConnected;
}
void DisableForConnect( HWND hWnd, BOOL bEnable )
{
EnableWindow( GetDlgItem( hWnd, IDC_CONNECT ), bEnable );
EnableWindow( GetDlgItem( hWnd, IDC_SEND ), bEnable );
EnableWindow( GetDlgItem( hWnd, IDC_RESETRECEIVE ), bEnable );
EnableWindow( GetDlgItem( hWnd, IDC_RESETSEND ), bEnable );
}
void EnableEdits( HWND hWnd, BOOL bEnable )
{
EnableWindow( GetDlgItem( hWnd, IDC_HOST ), bEnable );
EnableWindow( GetDlgItem( hWnd, IDC_PORT ), bEnable );
}
void EditPrint( HWND hWnd, char *format, ... )
{
char szData[1024] = {0};
va_list pArgList;
va_start( pArgList, format );
wvsprintf( szData, format, pArgList );
va_end( pArgList );
SetDlgItemText( hWnd, IDC_RECEIVED, szData );
}
void EditAppendPrint( HWND hWnd, char *szOutput, ... )
{
HWND hWndEdit;
int length;
char szBuffer[2048] = {0};
va_list pArgList ;
va_start ( pArgList, szOutput );
wvsprintf ( szBuffer, szOutput, pArgList );
va_end ( pArgList );
hWndEdit = GetDlgItem( hWnd, IDC_RECEIVED );
length = SendMessage( hWndEdit, WM_GETTEXTLENGTH , 0, 0 );
SendMessage( hWndEdit, EM_SETSEL, (WPARAM)length, (LPARAM)length );
SendMessage( hWndEdit, EM_REPLACESEL, (WPARAM)FALSE, (LPARAM)szBuffer );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -