[Receive] Windows Socket Network Program Design

xiaoxiao2021-03-14  199

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.

转载请注明原文地址:https://www.9cbs.com/read-129211.html

New Post(0)