📄 2003-01-02_cwinsock.cpp
字号:
/*
+-----------------------------------------------------------------------------+
| |
| cwinsock.cpp |
| Last change: yyyy-mm-dd |
| |
| Author: Jan Krumsiek |
| eMail: proxy@krumsiek.com |
| Web: http://www.krumsiek.com/proxy |
| |
| Copyright 2003 - Jan Krumsiek |
| This source code can freely be modified and redistributed. No liability |
| whatsoever is taken by the author for any use of this software. |
| |
| Description: |
| This is my socket implementation for windows, using WinSock |
| As all socket classes in this project have to, this module inherits |
| CSocket (in csocket.h) |
| |
+-----------------------------------------------------------------------------+
*/
#include "CWinsock.h"
#include "windows.h"
#include "winsock.h"
#include <signal.h> // signals
// private prototypes
CHARPTR GetErrorString(UINT error);
// global map that keeps links from HWNDs to old wndprocs and object pointers
SOCKOBJMAPPTR sockobjs = new SOCKOBJMAP;
// global functions for starting / stopping winsock for this process
void StartSockets() // exported
// starts winsock at all
{
// notification msg
printf("Starting sockets... \0");
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
MessageBox(0,"Error Couldnt Init Winsock!","Aborting",MB_ICONINFORMATION);
PostQuitMessage(0);
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
}
// notification msg
printf("Done\n\0");
return;
}
void StopSockets() // exported
// stops winsock
{
WSACleanup();
}
// Class definition
// *** Private members
SOCKET CWinsock::CreateSocket()
// this function creates a new socket, sets the event handler (window)
// and returns the created socket
{
SOCKET create;
// Create socket
create = socket(AF_INET,SOCK_STREAM,0);
if (create == INVALID_SOCKET)
return false;
// Set event notification for this socket
UINT ret = WSAAsyncSelect(create, hwnd,
WM_WSKEVENT,
FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE|FD_ACCEPT);
// Return socket
return create;
}
LRESULT CALLBACK CWinsock::WndProc(
HWND hwnd, // handle of window
UINT uMsg, // message identifier
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
)
// event handler for winsock (used for all CWinsock instances)
{
// Get SOCKWINDOW structure for this hwnd
CWinsock* sockobj = (*sockobjs)[hwnd];
SOCKET acc;
// Check if winsock notification msg
if (uMsg == WM_WSKEVENT)
{
// error?
UINT err = (WSAGETSELECTERROR(lParam));
if (err != 0)
{
// call error handler and leave proc
sockobj->errorhandler(wParam, err, GetErrorString(err));
}
// which message?
switch(WSAGETSELECTEVENT(lParam))
{
case FD_ACCEPT: // incoming connection request
// now accept connection
acc = accept(wParam, NULL, NULL);
// call accept handler saved in CWinsock instance
sockobj->accepthandler(acc);
return (0);
case FD_READ: // data arrival
UINT bytes;
char buff[1024];
// read until buffer is empty and send to event handler
while ((bytes = recv(wParam,buff,1024,0)) != SOCKET_ERROR)
sockobj->arrivalhandler(wParam,buff,bytes);
break;
case FD_CLOSE: // connection closed
// call event handler
sockobj->closehandler(wParam);
break;
case FD_CONNECT: // connection established
// call event handler
sockobj->connecthandler(wParam);
break;
default:
;
}
}
return 0;
}
CHARPTR GetErrorString(UINT error)
// returns a string containing an explanation text for a specific error code
{
switch (error)
{
case WSAEINTR:
return CopyString("Interrupted Function Call");
break;
case WSAEFAULT:
return CopyString("Bad Address");
break;
case WSAEINVAL:
return CopyString("Invalid Argument");
break;
case WSAEMFILE:
return CopyString("Too Many Open Files");
break;
case WSAEWOULDBLOCK:
return CopyString("Resource Temporarily Unavailable");
break;
case WSAEINPROGRESS:
return CopyString("Operation Now in Progress");
break;
case WSAEALREADY:
return CopyString("Operation Already in Progress");
break;
case WSAENOTSOCK:
return CopyString("Socket Operation on Non-Socket");
break;
case WSAEDESTADDRREQ:
return CopyString("Destination Address Required");
break;
case WSAEMSGSIZE:
return CopyString("Message Too Long");
break;
case WSAEPROTOTYPE:
return CopyString("Protocol Wrong Type for Socket");
break;
case WSAENOPROTOOPT:
return CopyString("Bad Protocol Option");
break;
case WSAEPROTONOSUPPORT:
return CopyString("Protocol Not Supported");
break;
case WSAESOCKTNOSUPPORT:
return CopyString("Socket Type Not Supported");
break;
case WSAEOPNOTSUPP:
return CopyString("Operation Not Supported");
break;
case WSAEPFNOSUPPORT:
return CopyString("Protocol Family Not Supported");
break;
case WSAEAFNOSUPPORT:
return CopyString("Address Family Not Supported by Protocol Family");
break;
case WSAEADDRINUSE:
return CopyString("Address Already in Use");
break;
case WSAEADDRNOTAVAIL:
return CopyString("Cannot Assign Requested Address");
break;
case WSAENETDOWN:
return CopyString("Network is Down");
break;
case WSAENETUNREACH:
return CopyString("Network is Unreachable");
break;
case WSAENETRESET:
return CopyString("Network Dropped Connection on Reset");
break;
case WSAECONNABORTED:
return CopyString("Software Caused Connection Abort");
break;
case WSAECONNRESET:
return CopyString("Connection Reset by Peer");
break;
case WSAENOBUFS:
return CopyString("No Buffer Space Available");
break;
case WSAEISCONN:
return CopyString("Socket is Already Connected");
break;
case WSAENOTCONN:
return CopyString("Socket is Not Connected");
break;
case WSAESHUTDOWN:
return CopyString("Cannot Send After Socket Shutdown");
break;
case WSAETIMEDOUT:
return CopyString("Connection Timed Out");
break;
case WSAECONNREFUSED:
return CopyString("Connection Refused");
break;
case WSAEHOSTDOWN:
return CopyString("Host is Down");
break;
case WSAEHOSTUNREACH:
return CopyString("No Route to Host");
break;
case WSAEPROCLIM:
return CopyString("Too Many Processes");
break;
case WSASYSNOTREADY:
return CopyString("Network Subsystem is Unavailable");
break;
case WSAVERNOTSUPPORTED:
return CopyString("winsock.dll Version Out of Range");
break;
case WSAHOST_NOT_FOUND:
return CopyString("Host Not Found");
break;
case WSATRY_AGAIN:
return CopyString("Non-Authoritative Host Not Found");
break;
case WSANO_RECOVERY:
return CopyString("This is a Non-Recoverable Error");
break;
case WSANO_DATA:
return CopyString("Valid Name, No Data Record of Requested Type");
break;
}
return CopyString("Unknown error.\0");
}
// *** Public members
// Constructor
CWinsock::CWinsock()
// Initialize
{
// Startup winsock
//WSAStartup(MAKEWORD(1,1), &winsock_data);
WNDPROC oldproc;
/* char szWindowClass[] = "proxclass\0";
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = GetModuleHandle(NULL);
wcex.hIcon = NULL;
wcex.hCursor = NULL;
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = NULL;
ATOM ret = RegisterClassEx(&wcex);*/
// Create window for notifications
//hwnd = CreateWindow(szWindowClass, "testwin\0", WS_OVERLAPPEDWINDOW,
// CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
hwnd = CreateWindow("STATIC", 0, WS_OVERLAPPEDWINDOW,
0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
// Subclass window
oldproc = (WNDPROC) ::SetWindowLong(hwnd, GWL_WNDPROC, (LONG)WndProc);
// Add to map
(*sockobjs)[hwnd] = this;
}
// Destructor
CWinsock::~CWinsock()
{
DestroyWindow(hwnd);
WSACleanup();
}
UINT CWinsock::Connect(CHARPTR host, USHORT port)
{
// connect to host
sockaddr_in addr;
SOCKET create;
// set address parameters
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(host);
// if no IP-address then s_addr=INADDR_NONE -> resolve address
if (addr.sin_addr.s_addr == INADDR_NONE)
{
hostent* shost;
shost = gethostbyname(host);
// now copy address
memcpy(&addr.sin_addr.s_addr,shost->h_addr_list[0],4);
}
// create socket
create = CreateSocket();
connect(create,(struct sockaddr*)&addr,sizeof(addr));
return create;
}
CWinsock::SetEventHandlers(t_connect connproc, t_accept acceptproc,
t_close closeproc, t_data arrivalproc,
t_error errorproc)
{
connecthandler = connproc;
accepthandler = acceptproc;
closehandler = closeproc;
arrivalhandler = arrivalproc;
errorhandler = errorproc;
}
CWinsock::Send(UINT socket, CHARPTR data, UINT length)
{
send(socket,data,length,0);
}
CWinsock::Sendsz(UINT socket, CHARPTR data)
{
send(socket,data,strlen(data),0);
}
void CWinsock::Close(UINT socket)
{
closesocket(socket);
}
CHARPTR CWinsock::GetPeerIP(UINT socket)
// get peer address
{
// get address in binary format first
sockaddr_in peer;
int peerlen;
peerlen = sizeof(sockaddr);
getpeername(socket,(sockaddr*)&peer, &peerlen);
// now convert to "dotted" format
return inet_ntoa(peer.sin_addr);
}
UINT CWinsock::Listen(UINT port)
// Start listening on port 'port'
{
sockaddr_in address;
// set struct parameters
address.sin_family = AF_INET;
address.sin_port = htons(port);
address.sin_addr.s_addr = INADDR_ANY;
// Get a socket
listensock = CreateSocket();
// Bind socket to local host
bind(listensock,(struct sockaddr*)&address,sizeof(address));
// Start listening
listen(listensock,5);
return listensock;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -