Windows Socket1.1 programming

xiaoxiao2021-03-06  39

First, introduction

Windows Sockets is expanded from Berkeley Sockets, which inherits Berkeley Sockets, and has been newly expanded. These expansion mainly provide some asynchronous functions and add a network event asynchronous selection mechanism that meets Windows message driver characteristics.

Windows sockets consists of two parts: development components and runtime components.

Developing Components: Windows Sockets Implement Document, Application Interface (API) Introduces Library and Some headers.

Run Components: Windows Sockets Application Dynamic Link Library (Winsock.dll).

Second, the main expansion description

1, asynchronous choice mechanism:

The asynchronous selection function of Windows Sockets provides a web event selection of the message mechanism. When using it to register the network event, the application corresponding window function will receive a message, and the message indicates the occurrence of the network event, and some related to the event. information.

Windows Sockets provides an asynchronous selection function WSaasyncSelect () that uses it to register a network event interested in the application. When these events occur, the application corresponding window function will receive a message.

The function structure is as follows:

Int Pascal Far Wsaasyncselect (socket S, HWND HWND, UNSIGNED INT WMSG, Long LEVENT)

Parameter Description:

HWND: Window handle

WMSG: Messages that need to be sent

Levent: Event (The following is the content of the event)

Value: meaning:

FD_READ expects to receive data (ie read ready) on the socket (ie read ready)

FD_WRITE expects to receive notifications when you can send data (ie, write ready) on the socket

FD_OOB expects to receive notifications when there are external data to arrive on the socket

FD_ACCEPT expects to receive notifications when there are foreign connections on the socket

FD_CONNECT expects to receive notifications when the socket connection is established

FD_CLOSE expects to receive notifications when the socket is closed

For example: We have to receive notifications when you read the symbol read ready or write, the statement is as follows:

RC = WSAASYNCSELECT (S, HWND, WMSG, FD_READ | FD_WRITE);

If we need to cancel the message to the socket network event, just set the Levent to 0

2, asynchronous request functions

The request service in Berkeley Sockets is blocked, in addition to supporting this type of function, in addition to supporting this type of function (WSAAsyncGetxByy ();).

3, blocking processing method

Windows Sockets Abandon the CPU for other applications to be run when an application's socket call is blocked, and it enters a routine called "hook" when calling in the call, this routine is responsible for receiving and assigning Windows messages allow other applications to still receive their own messages and achieve control.

Windows is a non-predetermined multitasking environment, that is, if a program does not actively give it to give control, other programs cannot be executed. Therefore, when designing the Windows Sockets program, although the system supports blocking operations, it is still opposed to programmers. However, due to the SUN's Berkeley Sockets socket default operations are blocking, Windows is also intended to support this operation as porting SOCKETS.

In the Windows Sockets implementation, the following processes are processed for blocked operations that cannot be completed immediately: DLL initialization → loop operation. In the loop, it sends any Windows messages and checks if this Windows sockets call is completed. It is necessary when necessary, it can discard the CPU to make other application execution (of course, there will be this kind of CPU with the ultra-thread, there will be this trouble ^ _ ^) . We can call the wsacancelblockingCall () function to cancel this blocking operation. In Windows Sockets, there is a default blocking process routine BlockingHook () simply acquires and sends a Windows message. If you want to process complex programs, WSASetBlockingHook () is available in Windows Sockets, providing users to install their own blocking process routine; SwaunhookBlockingHook () is SwaunhookBlockingHook (), which is used to delete any of previously installed occlusion processing examples Cheng, and reinstall the default processing routine. Note that when you design your own blocking process, in addition to the function WSAcAncelBlockingHook (), it cannot use other Windows Sockets API functions. Calling the wsacancelblockinghook () function in the process routine will cancel the blocking operation, which will end the blocking loop.

4, error handling

Windows Sockets is compatible with later multi-threaded environments (Windows / UNIX), it provides two error handages to get the nearest error number of the current thread. (Wsagetlasteror () and wsasetlasterror ())

5, start and termination

Use the function wsastartup () and wsacleanup () to start and terminate the socket.

Third, Windows Sockets Network Program Design Core

We can finally start the real Windows Sockets network program. But we still take a look at the content involved in each Windows Sockets network program. Let's walk slowly step by step.

1, start and termination

In all Windows Sockets functions, only start function wsastartup () and termination functions WSACLEANUP () must be used.

The startup function must be the first function, and it allows you to specify the version of the Windows Sockets API and get some specific technical details for Sockets. This structure is as follows:

INT Pascal Far Wsastartup (Word WversionRequested, LPWSADATA LPWSADATA);

WVersionRequested ensures that Sockets can run the DLL version, if not, return error messages.

Let's take a look at the code below, look at how to call WSAStartup ()

Word wversionRequested; // Define version information variables

WSADATA WSADATA; / / Define data information variables

INT ERR; / / Define Error number variables

WVersionRequested = MakeWord (1, 1); / / assigning version information

Err = WSAStartup (WVersionRequested, & WSADATA); / / Assignment to Error Information

IF (Err! = 0)

{

Return; / / tell the user to find the right version

}

/ / Confirm that Windows Sockets DLL supports 1.1 version

// DLL version can be higher than 1.1

/ / The version number returned by the system is always the minimum requirements 1.1, that is, the minimum version number supported in the application and the DLL.

IF (LobyTe (Wsadata.WVersion)! = 1 || Hibyte (Wsadata.WVersion)! = 1) {

WSACLEANUP (); // tells the user to find the right version

Return;

}

// Windows Sockets DLL is accepted by the process, you can go to the next step

When the function is used, any open and connected SOCK_STREAM socket is reset, but the sockets that have been closed by the closesocket () function but still have not transmitted data are not affected, and the unprecedable data will still be sent. . The WSASTARTUO () function may be called multiple times when running, but must ensure that the value of WVersionRequested each time the call is the same.

2, asynchronous request service

Windows Sockets has added a class of asynchronous request service functions WSAAsyncgerXByy () in addition to supporting the Synchronous requests in Berkeley Sockets. This function is an asynchronous version of the blocking request function. When the application calls it, this operation is initialized by the Windows Sockets DLL and returns the caller. This function returns an asynchronous handle to identify this operation. When the result is stored in the buffer provided by the caller, a message is sent to the application corresponding window. The common structure is as follows:

Handle Taskhnd;

Char Hostname = "RS6000";

Taskhnd = WsaasyncBethostByname (HWND, WMSG, Hostname, BUF, BUFLEN);

It should be noted that since Windows memory objects can be set to removable and discarded, the Wiindows Sockets DLL object must be used in operation memory objects.

3, asynchronous data transmission

Use the send () or sendto () function to send data, use RECV () or Recvfrom () to receive data. Windows Sockets does not encourage users to transfer data using blocked mode, because it may block the entire Windows environment. Let's take a look at an asynchronous data transfer instance:

Assume that the socket s has been used after the connection is established, and the function wsaasyncselect () has been used to register the network event fd_read and fd_write, and the WMSG value is UM_SOCK, then we can add the following branch statement in the Windows message loop:

Case um_sock:

Switch (lparam)

{

Case FD_READ:

Len = RECV (WPARAM, LPBUFFER, Length, 0);

Break;

Case FD_WRITE:

While (Send (WParam, Lpbuffer, Len, 0)! = Socket_ERROR)

Break;

}

Break;

4, error handling

Windows provides a function to get the most recent error code WsagetLastError (), the recommended write method is as follows:

Len = Send (s, lpbuffer, len, 0);

OF ((len == Socket_ERROR) && (wsagetlasterror () == wsawouldblock) {...}

Instance application:

WINSOCK API Research Based on Visual C

In order to facilitate network programming, in the early 1990s, Microsoft jointly developed a network programming interface under Windows, which is a Windows Sockets specification, which is not a network protocol, but a set of open, support more Network programming interface under Windows of the protocol. The current Winsock has basically implemented unrelated to the agreement, you can use Winsock to call the functions of multiple protocols, but more often use the TCP / IP protocol. Socket actually provides a communication port in your computer, which can communicate with any computer with a socket interface via this port. The application is transmitted on the network, and the received information is implemented by this socket interface. Microsoft defines the Winsock class such as CasyncSocket classes, which is derived from CasyncSocket, which is easy to use, and reader friends can of course use these classes to implement their own web programs, but in order to better understand Winsock API programming technology, we here Discuss how to use the underlying API function to achieve simple Winsock network application design, show how to operate Socket on the Server side and Client ends, implement data transfer based on TCP / IP, and finally give relevant source code.

When performing Winsock API programming in the VC, you need to use the following three files in the project, otherwise compile errors will occur.

1. Winsock.h: This is the header file of the Winsock API, which needs to be included in the project.

2. WSOCK32.LIB: Winsock API connection library file. In use, be sure to include it as a non-default connection library to the project file.

3. Winsock.dll: Winsock's dynamic connection library, located in the installation directory of Windows.

First, the server is operated Socket (socket)

1) Call WSAStartup in the initialization stage ()

This function initializes the Windows Sockets DLL in the application. Only after this function call is successful, the application can call the API function in other Windows Sockets DLLs. The form of this function is as follows: WSAStartup ((1 << 8 | 1), (LPWSADATA) & WSADATA), where (1 << 8 | 1) means that we use the Winsocket1.1 version, WSAATA is used to store information about Winsocket back by the system.

2) Establish Socket

After initializing the dynamic connection library of Winsock, you need to create a listening socket on the server side. To this end, you can call the socket () function to create this listening socket, and define the communication protocol used by this socket. This function call successfully returns the Socket object, returns invalid_socket (invoking wsagetlasterror () can be learned, all Winsocket functions can use this function to get the cause of the failure).

Socket Pascal Far Socket (int AF, INT TYPE, INT Protocol)

Parameters: AF: Currently only PF_INET (AF_INET);

Type: Socket type (Sock_Stream, Sock_DGRAM);

Protocol: Communication Agreement (if the user is not specified, set to 0);

If you want to build a socket, the second parameter TYPE should be SOCK_STREAM, such as the SOCKET of UDP (Data), should be SOCK_DGRAM.

3) Bind port

Next to specify an address and port (port) to specify the Socket defined by the server side, so that the client knows which port to connect to which address will be connected, to call the bind () function, the function call Successfully returns 0, otherwise returns Socket_ERROR.

INT Pascal Far Bind (Socket S, Const Struct Sockaddr Far * Name, Int Namelen);

Parameters: s: Socket object name;

Name: Socket's address value, this address must be the IP address of the machine in which this program is executed;

The length of Namelen: Name;

If the user does not care about the value of the address or port, the address can be set to INADDR_ANY, and the port is 0, and the Windows Sockets will automatically set it appropriate address and port (1024 to 5000). Thereafter, the getSockName () function can then be invoked to know the value set.

4) Listening

When the server-side Socket object bind is completed, the server side must establish a listening queue to receive the client's connection request. The listen () function enables the server-side socket to enter the listening state, and sets the maximum number of connections that can be established (the current maximum limit is 5, the minimum is 1). This function call successfully returns 0, otherwise returns socket_error.

Int Pascal Far Listen (Socket S, INT Backlog);

Parameters: S: Need to establish a listening socket;

Backlog: Maximum number of connections;

After the server-side Socket calls Listen (), if the client calls the connection CONNECT () function, the Server side must call the accept () function, so that the server side and the client formally complete the connection action of the communication program. . In order to know when the client proposes a connection request, the server-side socket is called the Accept () function to complete the establishment of the connection, let the system actively to inform us that the client proposes a connection request. . This function call successfully returns 0, otherwise returns socket_error.

Int Pascal Far Wsaasyncselect (socket S, HWND HWND, UNSIGNED INT WMSG, Long LEVENT)

Parameters: s: Socket object;

HWND: The window handle of the received message;

WMSG: The message to the window;

LEVENT: The registered network event, that is, a network event that the application sends a message to the window. This value is the following value fd_read, fd_write, fd_oob, fd_accept, combination of fd_oob, fd_close, the specific meaning of each value is fd_read: hope Receive a message when the socket S receives data; fd_write: You want to receive a message when you can send data on the socket s; FD_ACCEPT: I hope to receive a message when the connection request is received on the socket S; FD_CONNECT: I hope to receive a message when the connection is successful on the socket s; fd_close: I hope to receive a message when the connection is connected to the connection; fd_oob: I want to receive the message when I receive an external data on the socket S.

When specific applications, the WMSG should be the name name defined in the application, and LPARAM in the message structure is the above various network event names. So, you can use the following structure in the window handling custom message function to respond to the different events of Socket: Switch (LPARAM)

{CASE FD_READ:

...

Break;

Case FD_WRITE,

...

Break;

...

}

5) Server-terminal connection requests

When the client proposes a connection request, the Server-side HWND window will receive a Winsock Stack to send us a custom message. At this time, we can analyze LPARAM, then call related functions to handle this event. In order to allow the server to accept the client's connection request, use the accept () function, which creates a new socket and the client's Socket, and the original listener can continue to enter the listening status, waiting for the connection requirements of others. This function call successfully returns a newly generated socket object, otherwise returns invalid_socket.

Socket Pascal Far Accept (Scoket S, Struct SockAddr Far * Addr, Int Far * Addrlen);

Parameters: S: Socket identification code;

Addr: Store the address of the client connected;

Addrlen: The length of Addr

6) End Socket connection

The communication connection of the end server and client is very simple. This process can be started by any end of the server or client, as long as the closesocket () can be called, and the SOCKET to close the SERVER side monitoring is also used. . In addition, call the wsaStartup () number corresponding to the program, before the end, you need to call wsacleanup () to inform Winsock Stack release the resources occupied by Socket. Both functions are called successfully returned 0, otherwise returns socket_ERROR.

INT Pascal Far CloseSocket; Socket S

Parameters: s: Socket identification code;

INT Pascal Far WSacleanup (Void);

Parameter: None

Second, the operation of the client socket

1) Establish the client's socket

The client application first also calls the WSAStartup () function to establish a relationship with Winsock's dynamic connection library, then call socket () to create a TCP or UDP socket (Sockets of the same agreement to communicate, TCP TCP, UDP) . Unlike the server-side socket, the client's socket can call the bind () function, by yourself to specify the IP address and port number; however, Bind () can also be called, and the Winsock sets the IP address and Port number.

2) Propose connection application

The client's socket uses the connect () function to propose an application for establishing a connection with the server-side Socket, and the function call successfully returns 0, otherwise returns socket_ERROR.

Int Pascal Far Connect (Socket S, Const Struct Sockaddr Far * Name, INT Namelen);

Parameters: s: Socket identification code;

Name: Socket wants to connect the other party address;

Namelen: The length of Name

Third, data transmission

Although the service based on TCP / IP connection protocols (flow sleeve text) is the mainstream standard when designing client / server applications, but some services can also be provided by no connection protocols (Data Supply Settings). First, TCP Socket and UDP Socket feature when transmitting data: Stream (TCP) socket provides two-way, reliable, order, non-duplicated data transfer. Although DataGram (UDP) Socket provides two-way communication, there is no reliable, order, non-repetitive guarantee, so UDP transmission data may receive no order, repetitive information, and even missing in the transmission process. Since the UDP Socket is transmitted when the data is transmitted, the vast majority of applications use TCP to process Socket to ensure the correctness of the data. Under normal circumstances, the data transmission and reception of TCP Socket is to call send () and rec (), and UDP Socket is two functions of Sendto () and Recvfrom (), which calls success. When you play the length of the information sent or received, otherwise returns socket_error. Int Pascal Far Send (Socket S, Const Char Far * BUF, INT LEN, INT FLAGS);

Parameters: S: Socket identification code

BUF: State the provisional area for the information you want to transfer

Len BUF: length

Flags: how this function is called

For DataGram Socket, if the size of DataGram exceeds the limit, any information will not be sent and the error value will be sent back. For Stream Socket, in blocking mode, if the storage space in the transfer system is not stored in the transfer system, Send () will be held by Block until the data is delivered; if the socket is set to a non-blocking mode So how many information is sent as the current Output Buffer space, it will not be lived by Block. The value of Flags can be set to 0 or MSG_DONTROUTE and MSG_OOB combination.

Int Pascal Far Recv (Socket S, CHAR FAR * BUF, INT LEN, INT FLAGS)

Parameters: S: Socket identification code

BUF: Staff Region for the received information

Len BUF: length

Flags: how this function is called

For Stream Socket, we can receive valid information in Input Buffer, but its quantity does not exceed the size of the LEN.

Fourth, custom CMYSOCKET classes implement code:

According to the above knowledge, I have customized a simple CMYSocket class, below is part of the part of this class I defined:

//

CMYSOCKET :: CMYSocket (): File: // Class constructor

{

Wsadata WSAD;

Memset (m_lasterror, 0, err_maxlength);

// m_lasterror is the string variable in the class, initialization is used to store the string of the last error;

// Initialize the SockAddr_in structure variable in the class, the former stores the client address, the latter corresponding to the server side address;

MEMSET (& M_SockAddr, 0, sizeof (m_sockaddr);

MEMSET (& M_RSOCKADDR, 0, SIZEOF (M_RSOCKADDR);

Int result = WSAStartup ((1 << 8 | 1), & WSAD); // Initialize the Winsocket Dynamic Library; if (Result! = 0) // Initialization failed;

{SET_LASTERROR ("WSAStartup Failed!", WsageTlasterror ());

Return;

}

}

//

CMYSOCKET :: ~ cmysocket () {wsacleanup ();} // class destructor;

Int cmysocket :: Create (void)

{// m_hsocket is a class socket object, create a TCP / IP-based socket variable and assign the value to the variable;

IF ((m_hsocket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == Invalid_socket

{

SET_LASTERROR ("Socket () failed, wsagetlasterror ());

Return Err_wsaerror;

}

Return Err_Success;

}

///

INT CMYSOCKET :: Close (void) // Close the socket object;

{

IF (CloseSocket (M_HSocket) == Socket_ERROR)

{

SET_LASTERROR ("CloseSocket () FAILED, WSAGETLASTERROR ());

Return Err_wsaerror;

}

File: // Reset the SockAddr_in structure variable;

MEMSET (& M_SockAddr, 0, Sizeof (SockAddr_in));

MEMSET (& M_RSOCKADDR, 0, SIZEOF (SOCKADDR_IN));

Return Err_Success;

}

/

INT CMYSOCKET :: Connect (CHAR * STREMOTE, UNSIGNED INT IPORT) / / Define the connection function;

{

IF (strreMote) == 0 || iPort == 0)

Return Err_Badparam;

Hostent * hostent = NULL;

Long LipAddress = 0;

Hostent = gethostByname (strremote); / / Depending on the computer name to the relevant content of the computer;

IF (Hostent! = NULL)

{

Lipaddress = ((in_addr *) Hostent-> h_addr) -> s_addr;

m_sockaddr.sin_addr.s_addr = lipaddress;

}

Else

{

M_SockAddr.sin_addr.s_addr = inet_addr (strremote);

}

m_sockaddr.sin_family = af_INet;

m_sockaddr.sin_port = htons (iPort);

IF (Connect (m_hsocket, (sockaddr *) & m_sockaddr, sizeof (m_sockaddr)) == Socket_ERROR)

{

SET_LASTERROR ("Connect () failed, wsagetlasterror ());

Return Err_wsaerror;}

Return Err_Success;

}

///

INT CMYSOCKET :: Bind (Char * Strip, Unsigned INT IPORT) // Binding function;

{

IF (Strlen) == 0 || iPort == 0)

Return Err_Badparam;

MEMSET (& M_SockAddr, 0, sizeof (m_sockaddr);

m_sockaddr.sin_family = af_INet;

M_SockAddr.sin_addr.s_addr = inet_addr (strip);

m_sockaddr.sin_port = htons (iPort);

IF (bind (m_hsocket, (sockaddr *) & m_sockaddr, sizeof (m_sockaddr)) == Socket_ERROR)

{

SET_LASTERROR ("Bind () failed, wsagetlasterror ());

Return Err_wsaerror;

}

Return Err_Success;

}

//

INT CMYSOCKET :: Accept (socket s) // Establish a connection function, S is the name of the SOCKET object;

{

INT LEN = SizeOf (M_RSOCKADDR);

MEMSET (& M_RSOCKADDR, 0, SIZEOF (M_RSOCKADDR);

IF ((m_hsocket = accept (s, (sockaddr *) & m_rsockaddr, & len) == invalid_socket

{

SET_LASTERROR ("Accept () failed, wsagetlasterror ());

Return Err_wsaerror;

}

Return Err_Success;

}

/

INT CMYSOCKET :: asyncselect (hwnd hwnd, unsigned int wmsg, long levent)

File: // Event Selection Function;

{

IF (! iswindow (hwnd) || WMSG == 0 || LEVENT == 0)

Return Err_Badparam;

IF (Wsaasyncselect (M_HSocket, HWnd, WMSG, Levent) == Socket_ERROR)

{

SET_LASTERROR ("WSAAsYNCselect (), wsagetlasterror ());

Return Err_wsaerror;

}

Return Err_Success;

}

INT CMYSOCKET :: Listen (int queuedconnections) // Listening function;

{

IQ (iQueuedConnections == 0)

Return Err_Badparam;

IF (Listen (M_HSocket, iQueuedConnections) == Socket_ERROR)

{

SET_LASTERROR ("Listen () Failed", WsageTlasterror ());

Return Err_wsaerror;

}

Return Err_Success;

}

INT CMYSOCKET :: Send (Char * strdata, int Ilen) // data send function; {

IF (strData == null || Ilen == 0)

Return Err_Badparam;

IF (SEND (M_HSocket, Strdata, Ilen, 0) == Socket_ERROR)

{

SET_LASTERROR ("Send () failed, wsagetlasterror ());

Return Err_wsaerror;

}

Return Err_Success;

}

/

INT CMYSOCKET :: Receive (Char * strdata, int ILEN) // data reception function;

{

IF (strData == null)

Return Err_Badparam;

INT LEN = 0;

INT RET = 0;

RET = Recv (M_HSocket, StrData, Ilen, 0);

IF (RET == Socket_ERROR)

{

SET_LASTERROR ("RECV () failed, wsagetlasterror ());

Return Err_wsaerror;

}

Return Ret;

}

Void CMYSOCKET :: set_lasterror (char * newerror, int errnum)

File: // Winsock API Operation error string set function;

{

Memset (m_lasterror, 0, err_maxlength);

Memcpy (m_lasterror, newerror, strlen (newerror);

M_lasterror [Strlen (newError) 1] = '/ 0';

}

With the definition of the above classes, you can define the CMYSocket object, establish a connection, and transfer data. For example, in order to send data in the server and client, you need to define two CMYSocket objects in the server side, which are used to listen and connect, and the client defines a CMYSocket object clientSocket for transmitting or receiving data if the connection is established. The number is greater than one, and the CMYSocket object can be defined in the server side, but pay attention to not greater than five.

Since there are many Socket API functions, such as getting remote servers, local client IP addresses, host names, etc., readers can replenish CMYSocket, implement more features.

TCP / IP Winsock Programming Points

Using Winsock programming by synchronous and asynchronous mode, synchronous mode logic is clear, programming is focused on the application, in the predecessor multitasking operating system (WinNT, Win2K) is based on multi-threading efficiency basically reaches the level of asynchronous mode, should this be the following as synchronization Mode programming points.

1. Quick communication

Winsock's Nagle algorithm will reduce the transmission speed of small datagram, and the system is default to use Nagle algorithm, use

Int setsockopt

Socket S,

Int Level,

Int Optname,

Const Char Far * OptVal,

Int Optlen

); Function close it

example:

Socket sconnect;

Sconnect = :: Socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);

INT BNODELAY = 1;

Int err; err = setsockopt

Sconnect,

Ipproto_tcp,

TCP_Nodelay,

(char *) & bnodelay,

SiZoEOF (BNodelay)); // Does not use a delay algorithm

IF (Err! = NO_ERROR)

Trace ("Setsockopt Failed for Some REASON / N") ;;

2, Socket SEGMENTSIZE and Transceiver buffer

TCPSEGMENTSIZE is the maximum length of a single datagram, and the system defaults to 1460, and the transmission and receiving buffer is 8192.

In the SOCK_STREAM mode, if a single transmission data exceeds 1460, the system will be divided into multiple datagram, and the other party will be a data stream, the application needs to increase the judgment of the broken frame. Of course, the size of the 1460 can be changed in a modified registry, but Micrcosoft believes that 1460 is the best efficiency parameter, which is not recommended.

In the industrial control system, it is recommended to turn off the Nagle algorithm, each time the data is less than 1460 bytes (recommended 1400), so that each time you send a complete datagram, reducing the fault processing of the other party on the data stream.

3. The blocking time of the connection function when the network is reduced in the synchronous mode

When the internet network in the synchronization mode is about 20 seconds, it can be used to determine whether the path to the service host is passage, or first ping the IP address of the other host.

A. The gethostbyAddr blocked time regardless of the success of about 4 seconds.

example:

Long Lport = 3024;

Struct SockAddr_in ServerHostAddr; // Serve Host Address

ServerHostaddr.sin_Family = AF_INET;

ServerHostaddr.sin_Port = :: Htons (u_short (lport));

ServerHostAddr.sin_addr.s_addr = :: inet_addr ("192.168.1.3");

Hostent * PRESULT = gethostbyaddr (const char *) &

(ServerHostaddr.sin_addr.s_addr), 4, AF_INET);

IF (null == prelud)

{

INT NERRORCODE = WsageTlasterror ();

"GethostbyAddr ErrorCode =% D", NERRORCODE);

}

Else

{

Trace ("GethostbyAddr% S / N", PRESULT-> H_NAME) ;;

}

B, using ping mode for about 2 seconds

Temporary

4. Synchronous mode to solve the RECV, SEND blocking problem

Solve the SELECT function, check the read and write available status before the transceiver.

A, read

example:

TimeVal TV01 = {0, 1}; // 1 mS clock delay, actually 0-10 milliseconds

Int nselectret;

INT NERRORCODE;

FD_SET FDR = {1, Sconnect};

NSELECTRET = :: SELECT (0, & fdr, null, null, & TV01); // Check readable status

IF (socket_error == nselectret)

{

Nerrorcode = wsagetlasterror ();

Trace ("SELECT Read Status ErrorCode =% D", NERRORCODE);

:: CloseSocket; goto reconnect (customer party), or service thread exits (service party);

}

IF (NSELECTRET == 0) // timeout occurs, unable to read

{

Continue to read the state or actively send it to the other party

}

Else

{

Read data

}

B, write

TimeVal TV01 = {0, 1}; // 1 mS clock delay, actually 9-10 ms

Int nselectret;

INT NERRORCODE;

FD_SET FDW = {1, Sconnect};

NSELECTRET = :: SELECT (0, NULL, NULL, & FDW, & TV01); // Check

IF (socket_error == nselectret)

{

Nerrorcode = wsagetlasterror ();

"Select Write Status ErrorCode =% D", NERRORCODE);

:: CloseSocket (Sconnect);

// goto reconnect (customer party), or service thread exit (service party);

}

IF (NSELECTRET == 0) // timeout occurs, buffer full or network busy

{

/ / Continue to check the status or listening state

}

Else

{

//send

}

5. Change the TCP to send and receive buffer size

The system defaults to 8192, which can be changed as follows.

Socket sconnect;

Sconnect = :: Socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);

INT NRCVBUF = 1024 * 20;

INT Err = setsockopt

Sconnect,

Sol_socket,

SO_SNDBUF, // write buffer, read buffer to SO_RCVBUF

(char *) & nrcvbuf,

SizeOf (nrcvbuf);

IF (Err! = NO_ERROR)

{

Trace ("setsockopt error! / N");

}

Check if the buffer is set, check if it is really successful

INT GetSockopt

Socket S,

Int Level,

Int Optname,

Char far * Optval,

INT FAR * OPTLEN

);

6. Bind and Listen of the service party with multiple IP addresses

In applications with high reliability requirements, the dual network and multi-network channels are required, and the reputation is easy to implement, and the client can establish a customer request service for all IP addresses of the unit on port 3024 as follows.

Socket HserveSocket_ds = invalid_socket;

Struct SockAddr_in Hostaddr_ds; // Server Host Address

Long Lport = 3024;

Hostaddr_ds.sin_family = AF_INET;

Hostaddr_ds.sin_port = :: htons (u_short (lport));

Hostaddr_ds.sin_addr.s_addr = HTONL (INADDR_Any);

HSERVERSOCKET_DS = :: socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);

IF (hserversocket_ds == invalid_socket)

{

AFXMessageBox ("Building Data Server Socket Failed!");

Return False;

}

IF (socket_error == :: bind (hserversocket_ds, (structsockaddr *) (& (HostadDR_DS)), Sizeof (SockAddr))))

{

INT NERRORCODE = WsageTlasterror ();

Trace ("Bind Error =% D / N", NERRORCODE;

AFXMessageBox ("Socket Bind Error!");

Return False;

}

IF (socket_error == :: listen (hserversocket_ds, 10)) // 10 customers

{

AFXMessageBox ("Socket Listen Error!");

Return False;

}

AfxBeginthread (ServerThreadProc, Null, Thread_Priority_NORMAL);

After the client is complex, after the connection is broken, the renewal should be connected to a IP address connection. It is also possible to use simultaneous ways to connect.

7, realize variant client / server with TCP / IP Winsock

Traditional client / server is asked by the customer, the service answer, and the transmission and reception are paired. The variant Client / Server refers to the classification of customers and services in the connection. After building a good communication connection, no longer have strict customers and services, any party can actively send, need or do not need to answer the application Words, this approach is useful in the industrial control industry, such as RTDB as a customer of I / O Server, but I / O Server can actively send switch state displacement to the RTDB, followed by information. It is largely reduced network communication load and improves efficiency.

With 1-6 TCP / IP programming points, both the client and the Server have received priority, appropriate control timing can be implemented.

Windows Sockets API implements network asynchronous communication

Abstract: This article discusses and elaborates on how to use the connection-oriented stream sockets to make the network card programming and how to achieve asynchronous network communication.

I. Introduction

In the early 1980s, the University of California, the University of California, has developed an API specially used in network communication development for TCP / IP network communications. This API is a Socket interface (socket) - the most common API of TCP / IP network today is also an API that is most common on the Internet. After Microsoft combined with several other companies, it has developed a network programming interface for Windows, and some asynchronous functions are introduced in their specifications, the network event asynchronous selection mechanism is added, so it is more compliant with Windows messages. Features allows network developers to make a more convenient design of high-performance network communication programs. This article will discuss the connection-oriented stream socket programming for Windows Sockets API and the programming implementation of asynchronous network communication.

Second, the design of the connection-oriented stream socket programming model

This article uses a model-client / server model that uses the most commonly used in network programming. Such a client / server model is a non-symmetrical programming mode. The basic idea of ​​this mode is to divide the applications together into two parts of the function, running on different computers, and achieve a complete functionality through the division of labor between them. One of these modes is required as a server to respond and provide a fixed service to customers; the other part is used as a client program to request or request some service to request or require some kind of service.

This article selects a TCP / IP-based client / server model and a connection-oriented stream socket. Its communication principle is that the server side and the client must establish a communication socket, and the server should first enter the listening state, and then the client sleeve message issues a connection request. After receiving the request, the server is established to establish another socket. In communication, the socket responsible for listening is still listening. If you have other customers send a connection request, then build a socket. By default, you can receive up to 5 client connection requests, and establish communication relationships with it. Therefore, the design process of this program should be started first by the server, then start the client at a certain moment and connect it to the server. Server and client start must call the Windows Sockets API function socket () to create a socket sockets, then the server party calls bind () to bundle the socket with a local network address, then call listen () to make the socket The word is in a passive ready-to-receive state while specifying its request queue length. After this, the server can receive the connection of the client by calling accept (). Compared with the server, the client's work is relatively simple. After the client opens the socket, you can establish a connection by calling connect () and servers. After the connection is established, the customer and the server can be sent and received by connecting and receiving information. At the end of the final data transmission, both parties call CloseSocket () to close the socket to end this communication. The specific process block diagram of the entire communication process can be generally represented by the following flowcharts:

Drawing flow-oriented flow socket programming flow diagram

Third, software design points and realization of asynchronous communication

Depending on the program flow designed, the program can be divided into two parts: the server side and the client. And the entire implementation process can be generally peeled off with the following very critical Windows Sockets API functions:

Server side:

Socket () -> bind () -> listen-> acception () -> rec () / send () -> closesocket ()

Client machine:

Socket () -> connect () -> send () / recv () -> CloseSocket ()

In view of the importance of the above functions throughout the network programming, it is necessary to combine the program instance to do more in-depth analysis. The server-side application must first have a socket before using a socket, and the system calls the socket () function provides the application to create a socket. The socket is actually provided in a computer, which can communicate with any computer with a socket interface through this 埠. The application is transmitted on the network, and the received information is implemented by this socket interface. In the application development, like the file handle, you can read and write the socket:

SOCK = Socket (AF_INET, SOCK_STREAM, 0);

The first parameter of the function is used to specify the address family, only support AF_INET (TCP / IP address) under Windows; the second parameter is used to describe the type of socket, provide SOCK_STREAM for stream socket; last one The parameter specifies the protocol used by the socket, typically 0. The return value of this function saves the handle of the new socket, and can be released with a ClosSocket (Sock) before the program exits; function. Once a server side obtains a new socket, the socket should be associated with a port on the unit by bind ():

Sockin.sin_family = af_INET;

Sockin.sin_addr.s_addr = 0;

Sockin.sin_port = htons (userport);

Bind (Sock, (LPSOCKADDR) & sockin, sizeof (sockin));

The second parameter of this function is a pointer to the SockAddr_in structure type containing the native IP address and port information, and its member describes the local port number and the local host address. After bind () identify the server process on the network. . It should be noted that the number of stamped numbers within 1024 is therefore no particular need to generally not set the sign of SOCKIN.SIN_PORT to 1024. Then call the listen () function to start listening, then call the Accept () call waiting to receive the connection to complete the connection: // Connection Request queue length is 1, that is, only one request is allowed, if there is a number of requests,

// The error will appear and give the error code wsaeconnrefused.

Listen (SOCK, 1);

// Turn on the thread to avoid the blocking of the main program

AFXBEGINTHREAD (Server, NULL);

......

UINT Server (LPVOID LPVOID)

{

......

INT Nlen = SizeOf (SockAddr);

PView-> Newskt = Accept (PView-> Sock, (LPSOCKADDR) & PView-> Sockin, (LPINT) & NLEN);

......

WSaasyncselect (pView-> newskt, pview-> m_hwnd, wm_socket_msg, fd_read | fd_close);

Return 1;

}

The reason here is placed in a thread because the server will stop waiting for the connection request on the Accept statement when executing the function is executed, the server will stop waiting for the connection request on the Accept statement, which will be caused by the program. Blocking, although it is also possible to return the accept () function to return immediately when there is no customer waiting by setting the socket, but this polling sleeve text will make the CPU is busy waiting, thereby reducing The running efficiency of the program is a lot of system resources. Considering this situation, set the socket to block the working mode, and open a sub-thread separately, control it in the sub-thread range without causing the entire application. For the response of the network event, it is clear that the asynchronous selection mechanism is taken, and only the way to take this approach can immediately make timely response processing in the process when the unpredictable network event caused by the network, there is no online event. Other events can be handled when arriving, and this efficiency is very high, and it is fully compliant with the principle of messages triggered by Windows. The wsaasyncselect () function in the previous section is the core function of implementing an asynchronous selection of network events.

Through the fourth parameter registration application sense of online event, here, the network read and network disconnects are specified by fd_read | fd_close, and when this event occurs, the third parameter is specified by the third parameter. Define the message wm_socket_msg, and receive the message to specify its handle by the second parameter. In the message processing function, the network event can be distinguished by judging the message parameter low byte:

Void CNetServerview :: Onset (WPARAM WPARAM, LPARAM LPARAM)

{

INT IREADLEN = 0;

INT message = lparam & 0x0000FFF;

Switch (Message)

{

Case fd_read: // Read the event. At this time, there is a character reaching, requiring reception processing

Char CDataBuffer [MTU * 10];

// receive information through socket

Ireadlen = Recv (Newskt, CDataBuffer, MTU * 10, 0);

// Save information to the file

IF (! file.open ("ServerFile.txt", CFile :: ModeReadwrite))

File.Open ("E: ServerFile.txt", CFile :: ModeReate | CFILE :: ModeReadwrite; file.seektoend ();

File.write (CDataBuffer, IREADLEN);

File.Close ();

Break;

Case FD_Close: // Network Disconnect Event. At this time, the client is closed or exited.

... // Perform corresponding processing

Break;

DEFAULT:

Break;

}

}

Here you need to implement a response to custom messages WM_Socket_msg, you need to add its message mapping relationships in header files and implementation files:

head File:

// {{AFX_MSG (CNETSERVERVIEW)

//}} AFX_MSG

Void OnSocket (WPARAM WPARAM, LPARAM LPARAM);

Declare_message_map ()

Implement file:

Begin_MESSAGE_MAP (CNETSERVERVIEW, CVIEW)

// {{AFX_MSG_MAP (CNETSERVERVIEW)

//}} AFX_MSG_MAP

ON_MESSAGE (WM_Socket_msg, onsocket)

END_MESSAGE_MAP ()

When performing asynchronous choices, when using the WSAAsyncSelect () function, there is a special note that needs to be causing:

1. Upon continuous use of the WSAAsyncSelect () function, only the event of the second setting is valid, such as:

WSaasyncselect (S, HWND, WMSG1, FD_READ);

WSaasyncselect (S, HWND, WMSG2, FD_CLOSE);

This only transmits WMSG2 messages when the fd_close event occurs.

2. The asynchronous events set on the socket can be canceled by calling WSaasyncSelect (S, HWND, 0, 0) after setting the asynchronous selection;

3. The Windows Sockets DLL will only send a message to the corresponding application after a network event, and cannot send multiple messages. However, by using some functions implicitly allowed the message to reach the message, the corresponding message may be received again.

4. FD_CLOSE events will not occur after calling the closesocket () function to turn off the socket.

The above basic completion of the server side programming, the following to the client's implementation is simple, after using socket () creates a complete set, you only need to complete the connection with the server by calling connect (), the rest The work is exactly the same as the server: send / receive receipts with Send () / RECV (), with CloseSocket () Close the socket:

Sockin.sin_family = AF_INET; / / Address family

Sockin.sin_addr.s_un.s_addr = ipaddr; // Specify the server's IP address

Sockin.sin_port = m_port; // Specify the port number of the connection

INT NCONNECT = Connect (Sock, (LPSOCKADDR) & sockin, sizeof (sockin));

This paper takes a reliable connection-oriented flow socket. There are three functions such as Write (), Writev (), and send () on data transmission, where the first two are used to buffer transmission and central transmission, while send () transmits the controllable buffer, and also You can specify the transmission control flag to send or use the empty data of the MSG_OOB to send or for the MSG_DONTROUTE Troubleshooting Control option. The network number portion of the resider address specifies the network interface that the data is transmitted, so that it can be sent directly without the local finding mechanism. This is also the true difference between the same with the WRITE () function. Since the received data system call and sending data system calls are corresponding, the reception of the data is not described herein, and the corresponding three reception functions are: read (), readv (), and RECV (). Due to the full functionality of the latter, this article selects the Send () - RECV () function pair in implementation, and the appropriate transmission-receive function pair should be selected depending on the specific situation in the specific program. Summary: TCP / IP protocol is currently the main communication protocol of each network operating system is also an Internet communication protocol. This article implements the design of a connection-oriented stream socket network communication program based on TCP / IP protocol through the Windows Sockets API. And through asynchronous communications and multi-threading, the operational efficiency of the program is improved, and the occurrence of blocking occurs.

Implement a chat room program with the Sockets API of VC 6.0

1.vc Network Programming and Introduction to Windows Sockets API

VC supports network programming with socket support, Wininet support, MAPI, and ISAPI support. Among them, the Windows Sockets API is a TCP / IP network environment and is also the most common API on the Internet. The earliest American University Berkeley has developed an API for TCP / IP protocol under UNIX. This API is a famous Berkeley Socket interface (socket). After the desktop operating system enters the Windows era, the socket method is still inherited. In TCP / IP network communication environments, Socket data transfer is a special I / O, which is equivalent to a file descriptor with a function called-Socket () similar to the open file. It can be understood that Socket is actually a communication endpoint, through which the user's Socket program can communicate over the network and other socket applications. Socket exists in a "communication domain" (an abstract concept introduced to describe how a general thread is communicated with Socket, and exchange data with another domain. Socket has three categories. The first is SOCK_STREAM (streaming) to provide a connection-oriented reliable communication service, such as Telnet, HTTP. The second is SOCK_DGRAM (datagram), providing communication with unconnectless communication, such as UDP. The third is SOCK_RAW (original), mainly used for the development and test of protocols, support communication underlying operations, such as direct access to IP and ICMP.

2.Windows Socket mechanism analysis

2.1 Some basic Socket systems call

The main system calls include: socket () - Create Socket; Bind () - Binds the created Socket and the local port; Connect () and acception () - create a socket connection; Listen () - server monitoring request; Send () - the controlled buffer transmission of the data; RECV () - controllable buffer reception; CloseSocket () - Turn off the socket.

2.2Windows socket starts and termination

Start function WSAStartup () establishes a connection to the Windows Sockets DLL, and the termination function wsaclearup () terminates the use of the DLL, which must be used. 2.3 Asynchronous selection mechanism

Windows is a non-seizuated operating system without taking UNIX blocking mechanism. When a communication event is generated, the operating system should process the event based on the settings, and the WSAAsYNCselect () function is the corresponding event to select the system. When Socket receives one of the setup network events, a message will be given to the program window. This message will specify the Socket that generates a network event, an event type and error code that occurs.

2.4 Asynchronous data transmission mechanism

WSaasyncselect () Sets a WM_Socket message to the window after the response communication event is required to respond to the communication event on the socket. In the callback function of the window, the corresponding data transfer processing code should be added.

3. Description of the chat room program

3.1 Implementing ideas

The chat room program on the Internet is generally served with a server-side connection response. The user can log in to the server through the client program to the user on the same server, which is a connection-oriented communication process. Therefore, the program is to implement two part of the server and the client in the TCP / IP environment.

3.2 Server workflow

The server side creates a socket array with a socket () system (ie, the maximum number of receiving connection customers) is set, and Bind Bind () can be listened to the port to listen (). If there is a client connection request, select an empty socket in an array, assign the client address to this socket. Then log in successfully can chat on the server.

3.3 Client workflow

The client program is relatively simple, just establish a socket to connect and receive data by this socket after successfulness.

4. Core code analysis

Limited to the space, only the core code related to network programming is given, and other servers, such as chat text, display readers can be added by themselves.

4.1 Server-end code

Turn on the server function:

VOID ONSERVEROPEN () // Turn on server function

{

Wsadata wsadata;

Int IrrorCode;

Char chinfo [64];

IF (WSASTARTUP (Winsock_Version, & Wsadata) // Call Windows Sockets DLL

{MessageBeep (MB_ICONSTOP);

MessageBox ("Winsock does not initialize!", AFXGetAppName (), MB_OK | MB_ICONSTOP);

WSACLEANUP ();

Return;}

Else

WSACLEANUP ();

IF (gethostname (chinfo, sizeof (chinfo))

{ReportWinsockerr ("/ N unable to get the host! / N");

Return;}

CString cswinsockid = "/ n == >> The server function is on port: NO.";

CSWinsockid = ITOA (m_pdoc-> m_nserverport, chinfo, 10);

Cswinsockid = "/ n";

PrintString (cswinsockid); / / // In the program view displays the function of the prompt information, the reader can create it yourself.

m_pdoc-> m_hserversocket = socket (PF_INET, SOCK_STREAM, Default_Protocol);

// Create server-side socket, type SOCK_STREAM, connected communication if (m_pdoc-> m_hserversocket == invalid_socket)

{ReportWinsockerr ("Unable to create server socket!");

Return;}

m_pdoc-> m_sockserveradddr.sin_family = af_INet;

m_pdoc-> m_sockserveradddr.sin_addr.s_addr = incdr_any;

m_pdoc-> m_sockserveradddr.sin_port = htons (m_pdoc-> m_nserverport);

IF (bind (m_pdoc-> m_hserversocket, (lpsockaddr) & m_pdoc-> m_sockserveraddr,

SIZEOF (m_pdoc-> m_sockserveradddr)) == Socket_ERROR) / / Binds with the selected port

{ReportWinsockerr ("Unable to Bind Server Socket!");

Return;}

Irrorcode = WSAASYNCSELECT (m_pdoc-> m_hserversocket, m_hwnd,

WM_SERVER_ACCEPT, FD_ACCEPT);

// Set the corresponding network event of the server to fd_accept, that is, the connection request,

/ / Generate the corresponding message to the window is WM_SERVER_ACCEPT

Irror (IrrorCode == Socket_ERROR)

{ReportWinsockerr ("WsaasyncseLect Setup Failure!");

Return;}

IF (listen (m_pdoc-> m_hserversocket, queue_size) == Socket_ERROR) // Start listening to customer connection request

{ReportWinsockerr ("Server Socket Listening Failed!");

m_pparentMenu-> EnableMenuItem (id_server_open, mf_enable);

Return;}

m_bserverisopen = true; / / Surveillance whether the server is open

Return;

}

Respond to customer send chat text to server: on_mentage (wm_client_read, onclientread)

LResult OnClientRead (WPARAM WPARAM, LPARAM LPARAM)

{

INT IREAD;

INT IBUFFERLENGTH;

INT IEND;

INT IREMAINSPACE;

Char chinbuffer [1024];

INT I;

For (i = 0; (i

// MaxClient is the maximum number of servers to respond to connectivity

{}

IF (i == maxclient) Return 0L;

IBufferLength = IREMAINSPACE = SizeOf (chinbuffer);

IEND = 0;

Iremainspace - = IEND;

IbytesRead = Recv (M_AClientSocket [i], (lpstr) (chinbuffer Iend), ISPACEREMAINING, NO_FLAGS; // receive characters with a controllable buffer reception function RECV ()

IEND = IREAD;

IF (IbytesRead == Socket_ERROR) ReportWinsockerr ("Recv error!");

Chinbuffer [IEND] = '/ 0';

IF (lstrlen (chinbuffer)! = 0)

{PrintString (chinbuffer); // server-side text display

ONSERVERBROADCAST (chinbuffer); // The function of yourself, broadcast this customer's chat text to all connected customers

}

Return (0L);

}

For the customer disconnection, an FD_CLOSE message will be generated, which is only necessary to close the corresponding socket with closesocket (), which is relatively simple.

4.2 client code

Connect to the server:

Void onsocketconnect ()

{Wsadata wsadata;

DWORD DWIPADDR;

SockAddr_in SockAddr;

IF (WSASTARTUP (Winsock_Version, & Wsadata) // Call Windows Sockets DLL

{MessageBox ("Winsock can't initialize!", Null, mb_ok;

Return;

}

m_hsocket = socket (PF_INET, SOCK_STREAM, 0); // Create a connection-oriented Socket

SockAddr.sin_Family = AF_INET; // Using TCP / IP Protocol

SockAddr.sin_port = m_iport; // Client specified IP address

SockAddr.sin_addr.s_un.s_addr = dwipaddr;

INT NCONNECT = Connect (M_HSOCKET, (LPSOCKADDR) & SockAddr, SIZEOF (SockAddr)); / / Request connection

IF (nConnect)

ReportWinsockerr ("Connection Fails!");

Else

MessageBox ("successful connection!", Null, mb_ok;

INT IerrorCode = WSAASYNCSELECT (M_HSocket, M_HWND, WM_SOCKET_READ, FD_READ);

/ / Specify the response event to send the character to the server

Irror (IrrorCode == Socket_ERROR)

MessageBox ("Wsaasyncselect setting failed!");

}

The character transmitted by the receiving server also also uses the controllable buffer reception function RECV (), the client chat character sends the use of data controllable buffer send functions send (), which is relatively simple, and it will not be described here.

5. Small knot

By booking through the writing room program, you can basically understand the basic procedures and essentials of the Windows Sockets API programming. This program compiled in VC 6.0, runs well in a local area using Windows 98 / NT.

Make a simple local area network message transmission project with VC

This project is similar to the OICQ message transmission mechanism, but he can only send a simple string. Although it is simple, he is also a very good VC network learning example.

In this case, the Socket class with the VC belt has heavy loaded a class MySock class, which can be displayed in the customer's location. The following is the implementation process:

Establish an MFC single document project, the project is OICQ, select Windows Sockets support in the fourth step, and other default settings. For the sake of simplicity, you will change the About dialog as a sending information interface.

Here, by the loss dialog to get the transmitted string, send the string to the string when the focus is obtained. Create an OICQ class window to get the View class pointer, which in turn can be displayed. EXTERN CSTRING BB;

Void Caboutdlg :: ONKILLFOCUS (CWND * PNEww)

{

// Todo: Add your message Handler Code Here

CDIALOG :: ONKILLFOCUS (PNEwwn);

BB = m_edit;

}

For OICQVIEW classes

Char aa [100];

CSTRING MM;

CDC * PDC;

Class mysock: public csocket // derives the MySock class, this class has both

{public: void onRecEive (int NerrorCode) / / You can receive information at any time

{

Csocket :: Receive ((void *) AA, 100, 0);

mm = aa;

Cstring ll = ""; // Eliminate the previous message before displaying the message

PDC-> TextOut (50, 50, ll);

PDC-> TextOut (50, 50, mm);

}

}

Mysock sock1;

CSTRING BB;

Bool coicqview :: OnsetCursor (CWND * PWND, UINT NHITTEST, UINT MESSAGE)

{

CView :: OnsetFocus (Poldwnd);

// Todo: add your message handler code here and / or call default

BB = "BESTING:" BB; / / Determine the sender's identity is BESTING

Sock1.sendto (BB, 100, 1060, "192.168.0.255", 0); // Get the focus to send information in broadcast form, port number is 1060

Return CView :: OnsetCursor (PWND, NHITTEST, Message);

}

Int coicqview :: oncreate (lpcreatestruct lpcreatestruct)

{

IF (cview :: oncreate (lpcreatestructure) == -1)

Return -1;

Sock1.create (1060, SOCK_DGRAM, NULL); // Send a message in datagram

Static CclientDC WDC (this); // Get the current view class

PDC = & WDC;

// Todo: Add Your Specialized Creation Code Here

Return 0;

}

Run, open the About dialog, enter the send message, the Enter key can send information, is it a bit like QQ?

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

New Post(0)