⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket lib.cpp

📁 WinSocket网络编程
💻 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 + -