Windows Socket Network Program Design
Windows Sockets
Microsoft Windows
Network program design interface, it is from Berkeley Sockets
Expand it. Windows Sockets
Inheriting Berkeley Sockets
On the basis of the main features, it has an important expansion. These extensions are mainly provided with some asynchronous functions and increase Windows.
Network event asynchronous selection mechanism for message-driven features. These expansion facilitates application developers to comply with Windows
Programming mode software, it makes it in Windows
It is possible to develop high-performance network programs.
Socket network program design principle
Socket
BSD UNIX
The supplied network application programming interface, which uses the communication mechanism of the client / server, so that the network client and server side pass Socket
Implement connection and data exchange between networks. Socket
Provides a series of system calls, using these system calls to implement TCP, UDP, ICMP
And IP
The communication between multiple network protocols.
Socket
There are three main types: stream sockets, DataGram Sockets
Raw Sockets
. Street Socket
The interface defines a reliable connection-oriented service that implements unlike errorless sequential data transmission. It solves the congestion of the data by built-in flow control, and the application can send any length of data, and use the data as byte stream. DataGram Socket
The interface defines a connectionless service. The data is transmitted through each other, and the transfer of the package is disorderless and does not guarantee whether it is wrong, lost, and repeat. The length of the package is limited (implied in length 8,192bytes)
The maximum length can be set to 32,768bytes
). Raw Socket
Interface allows low-level protocols such as IP
And ICMP
Direct access, it is mainly used for new network protocol implementations.
Below we use a typical situation that happens-oriented transmission, Socket
Implementation of Network Communication.
clothes
Affirm
Be aware of
customer
Household
Socket ()
Bind ()
Listen ()
accept ()
Close ()
read ()
...
Write ()
Close ()
read ()
...
Write ()
Socket ()
Connect ()
Connection Establishment
Wait Connection for Client
......
Figure 6.3
Socket for connection-oriented protocol
transfer
From Figure 6.3
It can be seen that the relationship between the client and the server is not symmetrical, the server starts first, then starts the customer with the server to establish a connection at a certain time. Server and customers must be used to call socket ()
Create a socket (Socket)
), Then the server calls bind ()
Bind the socket with a local network address, then call listen ()
The socket is in a passive ready-to-receive state while specifying its request queue length, and then the server can call accept ()
To receive the connection. After the customer is built, you can call connect ()
Establish a connection with the server. After the connection is established, the client and server can send and receive data by connecting and receiving data (called read ()
Write ()
). Finally, the end of the data is ended, and the two parties calls Close ()
Close the socket.
6.3.2 Winsock's expansion to Socket
BSD Socket
Support blocking (blocking)
) And non-blocking (non_blocking
) Two ways of working. Work in blocking mode, connect ()
Accept (), read ()
And RECV ()
Wait until it is executed until it succeeds or error returns. Working in a non-blocking mode, these calls are immediately returned, but whether they are completed by queries to know. For Windows
This kind of non-charming multi-task operating system is very difficult to accept, for this purpose, Winsock
Try to be with BSD Socket
In addition to it, it is necessary to expand it.
Winsock
BSD Socket
The expansion is mainly based on the message, on the asynchronous access interface of the network event. Table 6.2
List Winsock
The expanded function function.
Table 6.2 Winsock
Expansion function menu
letter
number
name
Work
can
WsaasyncgetHostbyAddr ()
standard
Berkeley
function
Getxbyy
Asynchronous versions, for example: functions
WsaasyncgetHostByname ()
Provide standard
Berkeley
function
Gethostbyname
A message based asynchronous implementation.
WsaasyncgetHostByname ()
WSaasyncGetProtobyname ()
WSaasyncGetProtobynumber ()
WSaasyncgetServbyName ()
WSaasyncgetServByport ()
Wsaasyncselect ()
function
SELECT ()
Asynchronous version
WSACANCELASYNCREQUEST ()
Cancel function
WSaasyncGetxbyy
Example of execution
WSAcancelBlockingCall ()
Cancel a "blocked" in execution
API
transfer
WSacleanup ()
Termination is implicit
Windows Sockets DLL
Wsagetlasterror ()
Obtain
Windows Sockets API
Recent error number
WSAISBLOCKING ()
Inspection implicit
Windows Sockets DLL
Whether it blocks a call of current clues
WsasetBlockingHook ()
Set your application's own "block" processing function
Wsasetlasterror ()
Set
Windows Sockets API
Recent error number
WSAStartup ()
Initialization implies
Windows Sockets DLL
WSAUNHOKBLOCKINGHOOK ()
Restore the original "block" processing function
From Table 6.2
It can be seen that Winsock
The expansion function can be divided into the following categories:
(1)
Asynchronous choice mechanism
Asynchronous selection function wsaasyncselect ()
Allow applications nominating one or more network events, all non-blocking network I / O
Routines (such as send ()
And RECV ()
), Whether it is already used or ready, can be used as WSaasyncselect ()
Candidate selected by the function. Windows when the nominated network event occurs
The application's window function will receive a message, the message comes with the parameters indicating a nominated web event.
(2)
Asynchronous request routine
Asynchronous request routines allow applications to obtain information in asynchronously, such as WSaasyncGetxByy ()
Class functions allow users to request asynchronous services, these features are using standard Berkeley
The function is blocked. Function WSAcanceLasyncRequest ()
Allows the user to terminate a asynchronous request being executed.
(3)
Blocking treatment method
Winsock
Enter a "hook when the call is in blocking
"The routine, it is responsible for processing Windows
Message makes Windows
The message loop can continue. Winsock
Two functions are also available (WsaseTBlockingHook ()
WSAUNHOKBLOCKINGHOOK ()
) Let users set up and cancel their blocking processing routines. In addition, the function wsaisblocking () can detect whether the call is blocked, the function wsacncelblockingcall ()
You can cancel a blocking call.
(4)
Error handling
For the multi-neaser environment (such as Windows / NT)
) Compatible, Winsock
Two error handages WSAGETLASTERROR ()
Wsasetlasterror ()
To get and set the nearest error number of the clue.
(5)
Start and termination
Winsock
Application in using the above Winsock
Before the function, you must call WSAStartup ()
Function to Windows Sockets DLL
Initialization to negotiate Winsock
Version support and assign the necessary resources. You should call the function wsacleanup () before exiting the application.
Termination to Windows Sockets DLL
Use, and release resources to use the next time.
In these functions, Windows is implemented
The key to online real-time communication is asynchronous selection function WSaasyncselect ()
Use, its prototype is as follows:
Int Pascal Far Wsaasyncselect (SOCTET S, HWND HWND, UNSIGNED INT WMSG, long LEVENT);
It requests Windows Sockets DLL
In detecting
Upper LEVENT
When an event is hwnd
Send a message WMSG
. It automatically sets socket s
In non-blocking work mode. Parameter Levent
From Table 6.3
One or more of the events listed. For example, we are in the socket S
Read ready or write to get notifications, you can use the following statement:
RC = WSAASYNCSELECT (S, HWND, WMSG, FD_READ | FD_WRITE);
When the socket S
When a network event is nominated, the window hwnd
Will receive a message WMSG
, Variable LPARAM
The low word indicates an event that occurs in the network, and the high character indicates an error code. Applications can determine their next step by this information.
Table 6.3
Asynchronous selection network event table
value
Contain
Righteousness
FD_READ
Hope in socket
s
Received the data (ie read ready)
FD_WRITE
Hope in socket
s
Received a notification when sending data (ie, write ready)
FD_OOB
Hope in socket
s
Admitted to external data to the notification
FD_ACCEPT
Hope in socket
s
There is a notice when there is an external connection
FD_CONNECT
Hope in socket
s
Connection is notified when the connection is completed
FD_close
Hope in socket
s
Receive a notification when it is closed
6.3.3 Network Program Echo
An example of this chapter is a simple point-to-point network real-time communication program echo
. Examples two parts: customer program wecho.c
With server program wechos.c
. Its work process is: The server starts first, it is waiting for the customer's connection after creating a socket; the customer creates a socket after startup, then establish a connection with the server; after the connection is established, the client receives the keyboard input, then send the data to After the server, the server receives the data, it simply sends back, the client will display the data received in the window; so loop, when the customer receives the input data "Q
"When it turns off the connection and socket, the server is turned off when the user turns off the window.
6.3.3.1 Network Customer
First introduce the client program, the source file name is wecho.c
The contents are listed below. In order to facilitate the reader, it will be given in the form of a Chinese annotation in the program, and the reader can enhance the understanding of this section according to these annotations. / * This is a sample for Winsock. It Uses Winsock Routine to Communicate With Server Through A Port - Userport.
USAGE: Wecho ServerName * /
#include
#include
#include
#include
#include
#include
#include "wecho.h"
Handle
Hinst, asynchnd;
Char Server_address [256] = {0};
Char buffer [MAXGETHOSTSTRUCT];
Char far *
LPBuffer = & buffer [0];
Socket
S = 0;
int
CONNECTED = 0;
Struct SockAddr_in Dst_Addr;
Struct Hostent * Hostaddr;
Struct hostent
Hostnm;
Unsigned short
Port = Userport; //
User port number, should be greater than 1024
. The port number of the client and the server must be the same.
INT SOCK_TYPE = SOCK_STREAM;
Bool
INITWINDOW (HANDLE);
Long Far Pascal ClientProc (HWND, Unsigned, Uint, long)
Void
Alertuser (HWND, LPSTR);
Bool
Client (hwnd);
Bool
Set_select (hwnd, long);
Bool
Make_skt (hwnd);
Bool
Connect_skt (hwnd);
Bool
Send_pkt (hwnd, int);
int
Receive_pkt (hwnd);
Void
Close_skt (void);
Void
DisplayInfo (HWND, INT);
/ ************************************************** *********************************** /
Int Pascal
WinMain (Handle Hinstance, Handle Hprevinstance, LPSTR LPCMDLINE, INT NCMDSHOW)
{
Hwnd hwnd;
MSG msg;
LSTRCPY ((LPSTR) Server_Address, LPCMDLINE
IF (! hprevinstance)
IF (! initwindow (hinstance))
Return (NULL);
Hinst = hinstance;
HWnd = CREATEWINDOW ("ClientClass", "Windows Echo Client", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, HINSTANCE, NULL;
IF (! hwnd)
Return (NULL);
ShowWindow (HWND, NCMDSHOW);
UpdateWindow (HWND);
EnableMenuitem (GetMenu (HWND), IDM_STOP, MF_DISABED | MF_G_G_G_G_Disa; PostMessage (hwnd, wm_user, (wparam) 0, (lparam) 0);
While (GetMessage (& MSG, NULL, NULL, NULL) {
TranslateMessage (& MSG);
DispatchMessage (& MSG);
}
Return (msg.wparam);
}
Bool
INITWINDOW (Handle Hinstance)
{
WNDCLASSWNDCLASS;
WNDCLASS.Style = CS_HREDRAW | CS_VREDRAW;
WNDCLASS.LPFNWNDPROC = ClientProc;
WNDCLASS.CBCLSEXTRA = 0;
Wndclass.cbWndextra = 0;
WNDCLASS.HINSTANCE = HINSTANCE;
WNDCLASS.HICON = LOADICON (NULL, IDI_Application);
WNDCLASS.HCURSOR = loadingcursor (null, idc_arrow);
WNDCLASS.HBRBACKGROUND = color_window 1;
WNDCLASS.LPSZMENUNAME = (LPSTR) "ClientMenu";
WNDCLASS.LPSZCLASSNAME = (LPSTR) "ClientClass";
Return (RegisterClass & Wndclass);
}
Long Far Pascal
ClientProc (HWND HWND, Unsigned Message, Uint WPARAM, Long LPARAM)
{
Int length;
Wsadata wsadata;
Int status;
LPSTR MSGSTR;
Switch (Message) {
Case WM_User: //
User initialization message. Start Windows Sockets DLL
, Negotiation version support.
Status = WSASTARTUP (0x101, & WSADATA);
IF (status! = 0) {
Alertuser (hwnd, "wsastartup () failed / n");
PostquitMessage (0);
}
IF (LobyTe (Wsadata.WVersion)! = 1 || Hibyte (Wsadata.WVersion)! = 1) {
Alertuser (hwnd, "wsastartup () version not match / n");
WSACLEANUP ();
PostquitMessage (0);
}
//
Get the host information asynchronously through the host name.
Asynchnd = wsaasyncgethostbyname (hwnd, um_req,
Server_address, buffer, maxgethoststruct;
Break;
Case WM_COMMAND:
Switch (wparam) {
Case IDM_Start:
IF (! client (hwnd) {
Alertuser (HWND, "START FAILED");
EnableMenuItem (GetMenu (HWND), IDM_START, MF_ENABED);
EnableMenuItem (GetMenu (HWND), IDM_STOP, MF_DISABLED | MF_G_GRAYED);
}
Else {
EnableMenuItem (GetMenu (hwnd), IDM_Start,
MF_DISABED | MF_GRAYED);
EnableMenuItem (GetMenu (HWND), IDM_STOP, MF_ENABLED);
}
Break;
Case IDM_STOP:
WSacleanup (); //
Log out before logout Windows Sockets DLL
usage of.
PostquitMessage (0);
Break;
}
Break;
Case WM_CHAR:
IF (wparam == 'q' | wparam == 'q') {
Postmessage (HWND, WM_COMMAND, (WPARAM) IDM_STOP, (LPARAM) 0);
Break;
}
Postmessage (hwnd, um_sock, (wparam) WPARAM, (LPARAM) fd_userwrite;
Break;
Case um_req: //
Asynchronous request completion messages, the result is in the buffer.
IF (WsageTasyncerror (LPARAM)) {
Alertuser (hwnd, "wsaasyncgethostbyname error / n");
WSACLEANUP ();
PostquitMessage (0);
}
Memcpy (& Hostnm, lpbuffer, sizeof (struct hostent);
Break;
Case um_sock: //
Asynchronous selection message.
Switch (lparam) {
Case FD_CONNECT: //
The connection is established, and the sign is set.
CONNECTED = 1;
Break;
Case FD_READ: //
The data read is ready, read data and display.
IF ((length = receive_pkt (hwnd) == 0)
{
Alertuser (HWND, "Receive Packet Failed");
Close_skt ();
Break;
}
DisplayInfo (HWND, Length);
Break;
Case fd_write: //
Write ready.
Break;
Case FD_USERWRITE: //
User write data messages, send data.
IF (! connect) {
Alertuser (HWND, "Connection Not Created");
Break;
}
Length = 1;
Buffer [0] = (char) wparam;
IF (! (slend_pkt (hwnd, length)) {
Alertuser (HWND, "Packet Send Failed");
Close_skt ();
Break;
}
Break;
Case FD_Close: //
Connection is closed, set the sign.
CONNECTED = 0;
IF (WSaasyncselect (S, HWnd, 0, 0) == Socket_ERROR)
Alertuser (hwnd, "wsaasyncselect failed";
Alertuser (HWND, "Socket Has Been Closed);
EnableMenuItem (GetMenu (HWND), IDM_START, F_ENABLED);
EnableMenuItem (GetMenu (HWND), IDM_STOP, MF_DISABLED | MF_G_GRAYED);
Break;
DEFAULT:
IF (WsagetSelectError (LPARAM)! = 0) {
Alertuser (HWND, "Socket Report Failure);
Close_skt ();
Break;
}
Sprintf (msgstr, "lparam = 0x% lx, wparam = 0x% x", lparam, wparam;
Alertuser (HWND, MSGSTR);
Break;
}
Break;
Case WM_DESTROY:
Close_skt ();
WSacleanup (); //
Log out before logout Windows Sockets DLL
usage of.
PostquitMessage (0);
Break;
DEFAULT:
Return (DEFWINDOWPROC (HWND, MESSAGE, WPARAM, LPARAM);
}
Return (NULL);
}
Void
//
Alarm procedure.
Alertuser (HWND HWND, LPSTR LPSZWARNING)
{
MessageBox (HWND, LPSZWARNING, "Windows Client", MB_OK | MB_ICONEXCLAMATION
}
/ ************************************************** *********************************** /
Bool
//
The client creates a socket and establishes a connection.
Client (hwnd hwnd)
{
EnableMenuItem (GetMenu (HWND), IDM_START, MF_ENABED);
EnableMenuItem (GetMenu (HWND), IDM_STOP, MF_ENABLED);
IF (! make_skt (hwnd)) {//
Create a socket.
Close_skt ();
Return (False);
}
IF (! set_select (hwnd, fd_connect | fd_read | fd_write)) {//
Asynchronously select the online event.
Close_skt ();
Return (False);
}
IF (! connection_skt (hwnd)) {//
establish connection.
Close_skt ();
Return (False);
}
Return (TRUE);
}
/ ************************************************** *********************************** /
int
//
Receive the data subroutine.
Receive_pkt (hwnd hwnd)
{
Int errno, length, len;
Length = 1024;
IF ((Len = Recv (s, lpbuffer, length, 0)) == Socket_ERROR) {//
Receive network data.
Errno = wsagetlasterror ();
IF (errno == wsaewouldblock)
Return (TRUE);
Alertuser (HWND, "Received Failed");
Close_skt ();
Return (False);
}
Length = len;
IF (length == 0) {
Alertuser (HWND, "Connection Was Closed");
Close_skt ();
}
Return (Length);
}
Bool
//
Asynchronous selection subroutines.
Set_select (hwnd hwnd, long levent)
{
IF (WSaasyncselect (s, hwnd, um_sock, levent) == Socket_ERROR) {
Alertuser (hwnd, "wsaasyncselect failed";
Return (False);
}
Return (TRUE);
}
Bool
//
Create a socket subroutine.
Make_skt (hwnd hwnd)
{
IF ((s = socket, sock_type, 0) == invalid_socket) {
Alertuser (HWND, "Socket Failed");
Return (False);
}
Return (TRUE);
}
Bool
//
Establish a connector.
Connect_skt (HWND HWND)
{
Int errno;
MEMSET ((void *) & DST_ADDR, SIZEOF (DST_ADDR), 0);
DST_ADDR.SIN_FAMILY = AF_INET;
DST_ADDR.SIN_PORT = HTONS (Port);
DST_ADDR.SIN_ADDR.S_ADDR = * ((unsigned long *) Hostnm.h_addr_list [0]);
IF (Connect (S. (STRUCT SOCKADDR *) & DST_ADDR, SIZEOF (DST_ADDR)) == Socket_ERROR) {
Errno = wsagetlasterror ();
IF (Errno! = WSAEWOULDBLOCK) {
Alertuser (HWND, "" Connect Failed ");
Close_skt ();
Return (False);
}
}
Return (TRUE);
}
Bool
//
Send a data subroutine.
Send_pkt (HWND HWND, INT LEN)
{
Int length;
IF ((Length = Send (s, lpbuffer, len, 0)) == Socket_ERROR) {
Alertuser (HWND, "Send Failed");
Close_skt ();
Return (False);
}
Else if (Length! = len) {
Alertuser (HWND, "Send Length NOT Match!");
Close_skt ();
Return (False);
}
Return (TRUE);
}
Void
//
Turn off the socket.
Close_skt ()
{
IF (s) {
(Void) CloseSocket (s);
S = 0;
}
}
Void //
Displays the received data subroutine.
DisplayInfo (HWND HWND, INT LEN)
{
HDC DC;
Int L;
Char line [16];
Static int co = 0, ROW = 0;
Buffer [len] = 0;
IF (DC = GetDC (HWND)) {
L = WSPRINTF ((LPSTR) LINE, "% s", lpbuffer;
Textout (DC, 10 * COL, 16 * ROW, (LPSTR) LINE, L);
ReleaseDC (HWND, DC);
}
COL = LEN;
IF (col> 40) {
COL = 0; ROW ;
}
}
6.3.3.2 Network Server Program
Let's introduce the server program, the source file is named Wechos.c
The content is as follows:
#include
/ * This is a sample for Winsock. It Uses Winsock Routine as a Server to Communicate With Client Through a port - Userport.
USAGE: WechOS.exe * /
#include
#include
#include
#include
#include "wechos.h"
#define max_length
1024
Handle
Hinst;
charr
Buffer [MAX_LENGTH];
Char far *
LPBuffer = & buffer [0];
int
Length = 0;
Socket S = 0, Oldskt;
Struct SockAddr_in Dst_Addr;
Unsigned short
Port = Userport;
int
SOCK_TYPE = SOCK_STREAM;
Bool
INITWINDOW (HANDLE);
Long Far Pascal ServerProc (HWND, Unsigned, UINT, long);
Void
Alertuser (HWND, LPSTR);
Bool
Server (hwnd);
Bool
Set_select (hwnd, long);
Bool
Make_skt (hwnd);
Bool
Accept_skt (hwnd);
Bool
Send_pkt (hwnd, int);
Bool
Receive_pkt (hwnd, int *);
Void
Close_skt (socket);
/ ************************************************** *********************************** /
Int Pascal
WinMain (Handle Hinstance, Handle Hprevinstance, LPSTR LPCMDLINE, INT NCMDSHOW)
{
Hwnd hwnd;
MSG msg;
IF (! hprevinstance) {
IF (! initwindow (hinstance))
Return (NULL);
}
Else Return (NULL); // Don't Allow Another Server IS Executing
Hinst = hinstance;
HWnd = CREATEWINDOW ("ServerClass", "Windows Echo Server", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, HINSTANCE, NULL;
IF (! hwnd)
Return (NULL);
ShowWindow (HWND, NCMDSHOW);
UpdateWindow (HWND);
PostMessage (hwnd, wm_user, (wparam) 0, (lparam) 0);
While (GetMessage (& MSG, NULL, NULL, NULL) {
TRANSLATEMESSAGE (& MSG); DispatchMessage (& MSG);
}
Return (msg.wparam);
}
Bool
INITWINDOW (Handle Hinstance)
{
WNDCLASS WNDCLASS;
WNDCLASS.Style = CS_HREDRAW | CS_VREDRAW;
WNDCLASS.LPFNWNDPROC = ServerProc;
WNDCLASS.CBCLSEXTRA = 0;
Wndclass.cbWndextra = 0;
WNDCLASS.HINSTANCE = HINSTANCE;
WNDCLASS.HICON = LOADICON (NULL, IDI_Application);
WNDCLASS.HCURSOR = loadingcursor (null, idc_arrow);
WNDCLASS.HBRBACKGROUND = color_window 1;
WNDCLASS.LPSZMENUNAME = (LPSTR) "ServerMenu";
Wndclass.lpszclassname = (lpstr) "ServerClass";
Return (RegisterClass & Wndclass);
}
Long Far Pascal
ServerProc (HWND HWND, Unsigned Message, Uint WPARAM, Long LPARAM)
{
Wsadata wsadata;
Int status;
Switch (Message) {
Case WM_User: //
User message, initializing Windows Sockets DLL
, Negotiation version support.
Status = WSASTARTUP (0x101, & WSADATA);
IF (status! = 0) {
Alertuser (hwnd, "wsastartup () failed / n");
PostquitMessage (0);
}
IF (LobyTe (Wsadata.WVersion)! = 1 || Hibyte (Wsadata.WVersion)! = 1) {
Alertuser (hwnd, "wsastartup () version not match / n");
WSACLEANUP ();
PostquitMessage (0);
}
IF (! Server (hwnd) {
Alertuser (HWND, "START FAILED");
EnableMenuItem (GetMenu (HWND), IDM_START, MF_ENABED);
EnableMenuItem (GetMenu (HWND), IDM_EXIT, MF_DISABLED | MF_G_GRAYED
}
Break;
Case WM_COMMAND:
Switch (wparam) {
Case IDM_Start:
IF (! Server (hwnd) {
Alertuser (HWND, "START FAILED");
EnableMenuItem (GetMenu (HWND), DM_START, MF_ENABED);
EnableMenuItem (GetMenu (hwnd), IDM_EXIT,
MF_DISABED | MF_GRAYED);
}
Break;
Case idm_exit:
WSacleanup (); //
Log out before logout Windows Sockets DLL
usage of.
Postquitmessage (0); Break;
}
Break;
Case um_sock: //
Asynchronous selection message.
Switch (lparam) {
Case FD_Accept: //
Receive connections on a socket.
IF (! accept_skt (hwnd)) {
Alertuser (HWnd, "Accept socket failed");
Break;
}
Set_select (hwnd, fd_read);
Break;
Case FD_READ: //
The data read is ready to receive network data.
Length = 1024;
IF (! Receive_pkt (hwnd, & length)) {
Alertuser (HWND, "Receive Packet Failed");
Break;
}
Set_select (hwnd, fd_write);
Break;
Case fd_write: //
Write ready, send data.
IF (! (slend_pkt (hwnd, length)) {
Alertuser (HWND, "Send Packet Failed");
Break;
}
Set_select (hwnd, fd_read);
Break;
Case FD_Close: //
Connection is closed.
IF (WSaasyncselect (S, HWnd, 0, 0) == Socket_ERROR)
Alertuser (hwnd, "wsaasyncselect failed";
Alertuser (HWND, "Socket Has Been Closed);
EnableMenuItem (GetMenu (HWND), IDM_START, MF_ENABED);
Break;
DEFAULT:
IF (WsagetSelectError (LPARAM)! = 0) {
Alertuser (HWND, "Socket Report Failure);
Close_skt (s);
S = Oldskt;
EnableMenuItem (GetMenu (HWND), IDM_START, F_ENABLED);
}
Break;
}
Break;
Case WM_DESTROY:
WSacleanup (); //
Log out before logout Windows Sockets DLL
usage of.
PostquitMessage (0);
Break;
DEFAULT:
Return (DEFWINDOWPROC (HWND, MESSAGE, WPARAM, LPARAM);
}
Return (NULL);
}
Void
//
Alarm procedure.
Alertuser (HWND HWND, LPSTR LPSZWARNING)
{
MessageBox (HWND, LPSZWARNING, "Windows Server", MB_OK | MB_ICONEXCLAMATION;
}
/ ************************************************** *********************************** /
Bool
//
Server program creates a socket and register FD_ACCEPT
Network event.
Server (hwnd hwnd)
{
EnableMenuItem (GetMenu (HWND), IDM_START, MF_DISABLED | MF_G_GRAYED);
EnableMenuItem (GetMenu (HWND), IDM_EXIT, MF_ENABED);
IF (! make_skt (hwnd))
Return (False);
IF (! set_select (hwnd, fd_accept) Return (false);
Return (TRUE);
}
/ ************************************************** *********************************** /
Bool
//
Receive the data subroutine.
Receive_pkt (HWND HWND, INT * LEN)
{
INT length, errno;
Length = * len;
IF ((LENGTH = RECV (S, LPBuffer, Length, 0)) == Socket_ERROR) {
Errno = wsagetlasterror ();
IF (errno! = WSAEWOULDBLOCK)
Return (False);
}
* len = length;
Return (TRUE);
}
Bool
//
Asynchronous selection subroutines.
Set_select (hwnd hwnd, long levent)
{
IF (WSaasyncselect (s, hwnd, um_sock, levent) == Socket_ERROR) {
Alertuser (hwnd, "wsaasyncselect failed";
Return (False);
}
Return (TRUE);
}
Bool
//
Create a socket subroutine.
Make_skt (hwnd hwnd)
{
SockAddr_in sin;
Unsigned long on = 1;
S = Socket (AF_INET, SOCK_STREAM, 0); //
Create a socket.
IF (s == invalid_socket) {
Alertuser (HWND, "Socket Failed");
PostquitMessage (0);
Return (False);
}
sin.sin_family = af_INet;
sin.sin_addr.s_addr = 0;
Sin.sin_port = HTONS (port);
IF (Bind (LPSOCKADDR) & sin, sizeof (sin))) {//
Establish a local connection.
Close_skt (s);
PostquitMessage (0);
Return (False);
}
IF (Listen (S, 1)) Return (False); //
The socket is changed to the passive sleeve, waiting for the reception connection.
Return (TRUE);
}
Bool
//
The receiving socket is connected.
Accept_skt (hwnd hwnd)
{
Socket newskt;
Struct SockAddr TcPaddr;
Int Len;
Len = sizeof (struct sockaddr);
Newskt = accept (s, (struct sockaddr far *) & tcpaddr, (int far *) & len;
IF (newskt == invalid_socket)
Return (False);
Else {
Oldskt = S; //
Save the listener socket.
S = newskt; //
Use reception sockets for data transfer.
}
Return (TRUE);
}
Bool
//
Send a data subroutine.
Send_pkt (HWND HWND, INT LEN)
{
IF (Send (S, LPBuffer, Len, 0) == Socket_ERROR)
Return (False);
Return (TRUE);
}
Void
//
Turn off the socket.
Close_skt (socket SKT)
{
(Void) CloseSocket (SKT);
}
Customer / Server Working Mode is Socket
The typical mode of the network program, through the understanding of this example program, we can basically master Windows Sockets
Basic Principles and Implementation Methods of Network Program Design. Users can use this program as an example to modify and expand them, and design the applications that meet yourself.