unit10 winsock messagedriven - 中国传媒大学 计算...

30
Windows Socket Message-Driven/WSAAsyncSelect Model Prof. Lin Weiguo Copyleft © 2009~2017, School of Computing, CUC Dec 2017

Upload: phamdiep

Post on 21-May-2018

229 views

Category:

Documents


2 download

TRANSCRIPT

Windows SocketMessage-Driven/WSAAsyncSelect Model

Prof. Lin WeiguoCopyleft © 2009~2017, School of Computing, CUC

Dec 2017

Note

Advanced Windows Network Programming

} You should not assume that an example in this presentation is complete. Items may have been selected for illustration. It is best to get your code examples directly from the textbook and modify them to work. Use the lectures to understand the general principles.

2 2017/12/5

Windows Message Processing

Advanced Windows Network Programming

} Windows Messages} Windows-based applications are event-driven. They do not

make explicit function calls to obtain input. Instead, they wait for the system to pass input to them.

} The system passes input to a window procedure in the form of messages. Messages are generated by both the system and applications.

} How a Single-Threaded Program Processes Messages

3 2017/12/5

MSG message;while (::GetMessage(&message, NULL, 0, 0)) {

::TranslateMessage(&message);::DispatchMessage(&message);

}

Message-driven Execution (Asynchronous):

Advanced Windows Network Programming4 2017/12/5

Message-Driven I/O

Advanced Windows Network Programming

} Windows specific variant of non-blocking I/O} The I/O functions continue to run in the background

and the program is notified if:} I/O operations are completed} I/O operations can be executed} An I/O error occurred

} Notification is done using window messages. Each Windows application (must have a GUI) has a message loop that processes window messages and other messages} When we use Message-Driven I/O, we define a custom

message that is sent to the message loop to notify us about the status of IO operations.

5 2017/12/5

Message Flow

Advanced Windows Network Programming6 2017/12/5

Win32 API Message Processing

Advanced Windows Network Programming

} Every Window element has an associated Window Procedure -registered when the Window is created, for processing messages.

7 2017/12/5

LRESULT WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam ){

switch (iMessage){

case WM_CREATE:DoCreate();break;

case WM_PAINT:Paint();break;

case WM_DESTROY:PostQuitMessage( 0 );break;

default:return DefWindowProc( hWnd, iMessage, wParam, lParam );

}return 0;

}

MFC: Message Mapping Macro

Advanced Windows Network Programming8 2017/12/5

// Example for BEGIN_MESSAGE_MAPBEGIN_MESSAGE_MAP( CMyWindow, CFrameWnd )

ON_WM_PAINT()ON_COMMAND( IDM_ABOUT, OnAbout )

END_MESSAGE_MAP( )

BEGIN_MESSAGE_MAP(CComputeDlg, CDialog)ON_BN_CLICKED(IDC_START, &CComputeDlg::OnBnClickedStart)ON_BN_CLICKED(IDC_CANCEL, &CComputeDlg::OnBnClickedCancel)ON_WM_TIMER()

END_MESSAGE_MAP()

Create Message-driven Socket

Advanced Windows Network Programming

} Winsock provides a useful asynchronous I/O model that allows an application to receive Windows message–based notification of network events on a socket. This is accomplished by calling the WSAAsyncSelect function after creating a socket.

} Create Message-driven Socket } Step 1: Create a socket as usual.} Step 2: Use the WSAAsyncSelect function to turn the socket

into a message-driven socket.

9 2017/12/5

Note: The WSAAsyncSelect and WSAEventSelect models provide asynchronous notification of the capability to read or write data. It does not provide asynchronous data transfer like the overlapped and completion port models.

WSAAsyncSelect

Advanced Windows Network Programming

} The WSAAsyncSelect function requests Windows message-based notification of network events for a socket.

10 2017/12/5

int WSAAsyncSelect(__in SOCKET s,__in HWND hWnd,__in unsigned int wMsg,__in long lEvent

);

Parameterss [in]: A descriptor that identifies the socket for which event notification is required.hWnd [in] A handle that identifies the window that will receive a message when a network event occurs.wMsg [in] A message to be received when a network event occurs.lEvent [in] A bitmask that specifies a combination of network events in which the application is interested.

Note: socket() creates a socket in blocking mode,WSAAsyncSelect() turns it to non-blocking mode.

User-Defined Winsock Message

Advanced Windows Network Programming

} Declare user message ID

} Declare message handling function in the .h file

} Map the message to the handling function in .cpp file

} Implement the message handling functon in .cpp file

11 2017/12/5

#define WM_WINSOCK (WM_USER + 100)

BEGIN_MESSAGE_MAP(CMYDlg, CDialog)…

ON_MESSAGE(WM_WINSOCK, OnWinsock)END_MESSAGE_MAP()

…afx_msg LRESULT OnWinsock(WPARAM wParam, LPARAM lParam);DECLARE_MESSAGE_MAP()

LRESULT CMyDlg::OnWinsock(WPARAM wParam, LPARAM lParam){ ... return 0; }

Winsock Message Posting

Advanced Windows Network Programming12 2017/12/5

Posting winsock message

Advanced Windows Network Programming13 2017/12/5

int CMyDlg::StartMsgDrivenReceive(){

// ...int err = WSAAsyncSelect ( socket,

m_hWnd, // Window handle, from MFC’s CWindowWM_WINSOCK,FD_READ | FD_ACCEPT | FD_CLOSE);

if (err != 0){

afxMessageBox("WSAAsyncSelect() failed!“);// ...

}// ...

}

Network Event Types for the WSAAsyncSelect Function

Advanced Windows Network Programming

Event Type Meaning

FD_READ The application wants to receive notification of readiness for reading.

FD_WRITE The application wants to receive notification of readiness for writing.

FD_OOB The application wants to receive notification of the arrival of OOB data.

FD_ACCEPT The application wants to receive notification of incoming connections.

FD_CONNECT The application wants to receive notification of a completed connection or a multipoint join operation.

FD_CLOSE The application wants to receive notification of socket closure.

FD_QOS The application wants to receive notification of socket QOS changes.

FD_GROUP_QOS The application wants to receive notification of socket group QOS changes (reserved for future use with socket groups).

FD_ROUTING_INTERFACE_CHANGE

The application wants to receive notification of routing interface changes for the specified destination(s).

FD_ADDRESS_LIST_CHANGE

The application wants to receive notification of local address list changes for the socket's protocol family.

14 2017/12/5

Setting the Event parameter

Advanced Windows Network Programming15 2017/12/5

//a typical clientWSAAsyncSelect(s, m_hwnd, WM_SOCKET,

FD_CONNECT │ FD_READ │ FD_WRITE │ FD_CLOSE);

WSAAsyncSelect(Sockfd,m_hwnd,WM_SOCKET,FD_READ|FD_WRITE); // Activate both read & write.

WSAAsyncSelect(Sockfd, hMyWindow, WM_SOCKET,

0 // Disable all events.);

Server side WSAAsyncSelect

Advanced Windows Network Programming16 2017/12/5

SOCKET Listen = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);// Bind the socket to port 5150 and begin listening for connectionsInternetAddr.sin_family = AF_INET;InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);InternetAddr.sin_port = htons(5150);

bind(Listen, (PSOCKADDR) &InternetAddr, sizeof(InternetAddr));

// Set up window message notification on// the new socket using the WM_SOCKET define above

WSAAsyncSelect(Listen, Window, WM_SOCKET, FD_ACCEPT │ FD_CLOSE);

listen(Listen, 5);

// Translate and dispatch window messages// until the application terminateswhile (1) {// ...

Processing Winsock Message

Advanced Windows Network Programming17 2017/12/5

LRESULT CMyDlg::OnWinsock(WPARAM wParam, LPARAM lParam){

SOCKET sock = (SOCKET) wParam;int event = WSAGETSELECTEVENT(lParam);int WsaErr = WSAGETSELECTERROR(lParam);

// Determine whether an error occurred on the socket by using the WSAGETSELECTERROR() macroif (WsaErr) { closesocket( sock ); return 0; }

switch(event)// Determine what event occurred on the socket{

case FD_ACCEPT:OnAccept( sock ); break; // Accept an incoming connection

case FD_READ:OnRead( sock ); break; // Receive data from the socket in wParam

case FD_WRITE:OnWrite( sock ); break; // The socket in wParam is ready for sending data

case FD_CLOSE:closesocket( sock); break; // The connection is now closed

}return 0;

}

Processing Winsock Event:OnAccept()

Advanced Windows Network Programming18 2017/12/5

Void CMyDlg::OnAccept(SOCKET mysocket){

SOCKET AcceptedSock = accept(mysocket, NULL, NULL);if (total_conn >= MAX_CLIENT_NUM) //close if more than MAX client number{

closesocket(AcceptedSock); return;}ClientSock[CurConn].Sock=AcceptedSock; //save the new socket to the connected list

// Prepare accepted socket for read, write, and close notificationWSAAsyncSelect(AcceptedSock, m_hWnd, WM_SOCKET, FD_READ │ FD_WRITE │ FD_CLOSE);…

}

Void CMyDlg::OnRead(SOCKET mysocket){

if (mysocket==ServerSock_UDP) //UDP Echo{ recvfrom(…); sendto(…);}

else if (mysocket!=ServerSock) //TCP Time server{ recv(…); send(…);}

}

Alternative way for processing User-Defined Message

Advanced Windows Network Programming

} Step 1:} Select the dialog class in the

Class view.} Step 2:

} Go to Properties view.} Click the icon for overrides (a

green cube in VS.NET 2008).} Find “Window Proc” in the

list.} Open the drop-list and select

“<Add> Window Proc”.

19 2017/12/5

Alternative way for processing User-Defined Message

Advanced Windows Network Programming

} Step 3:} Add code to filter the defined custom message for network

events

20 2017/12/5

// Override MFC's Window procedure to process the Winsock messages.LRESULT CMyDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam){

// TODO: Add your specialized code here and/or call the base classif (message == WM_WINSOCK) {

int event = WSAGETSELECTEVENT(lParam);int wsaerr = WSAGETSELECTERROR(lParam);switch (event) {

case FD_READ : OnRead(); return 0;case FD_ACCEPT : OnAccept(); return 0;case FD_CLOSE : OnClose(); return 0;

}}return CDialog::WindowProc(message, wParam, lParam);

}

Winsock Event Triggering

Advanced Windows Network Programming

} Edge-Triggered v.s. Level Triggered} Re-enabling functions

21 2017/12/5

Winsock Event Triggering

Advanced Windows Network Programming

} Level Trigger example: FD_READ

22 2017/12/5

Winsock Event Triggering

Advanced Windows Network Programming

} Edge Trigger example: FD_WRITE

23 2017/12/5

On Write

Advanced Windows Network Programming24 2017/12/5

case FD_WRITE: // write event{

while(TRUE){// read from a file into packet.data.in.read((char*)&packet.data, MAX_PACKET_SIZE);

// sending dataif (send(wparam, (char*)(&packet), sizeof(PACKET), 0) == SOCKET_ERROR)

{if (WSAGetLastError() == WSAEWOULDBLOCK){

break; // socket internal buffer full} else // other errors{

// output error message, and return.CleanUp();return(0);

}}

}} break;

summary of events and conditions for asynchronous notification message.

Advanced Windows Network Programming

} FD_READ: 1. When WSAAsyncSelect is called, if there is data currently available to receive.2. When data arrives, if FD_READ is not already posted.3. After recv or recvfrom is called, with or without MSG_PEEK, if data is still

available to receive.

} FD_WRITE: 1. When WSAAsyncSelect called, if a send or sendto is possible.2. After connect or accept called, when connection established.3. After send or sendto fail with WSAEWOULDBLOCK, when send or sendto

are likely to succeed.4. After bind on a connectionless socket. FD_WRITE may or may not occur at

this time (implementation-dependent). In any case, a connectionless socket is always writeable immediately after a bind operation.

25 2017/12/5

summary of events and conditions for asynchronous notification message.

Advanced Windows Network Programming

} FD_ACCEPT:1. When WSAAsyncSelect called, if there is currently a connection request available to accept.

2. When a connection request arrives, if FD_ACCEPT not already posted.3. After accept called, if there is another connection request available to accept.

} FD_CONNECT:1. When WSAAsyncSelect called, if there is currently a connection

established.2. After connect called, when connection is established, even when connect

succeeds immediately, as is typical with a datagram socket.3. After calling WSAJoinLeaf, when join operation completes.4. After connect, WSAConnect, or WSAJoinLeaf was called with a

nonblocking, connection-oriented socket. The initial operation returned with a specific error of WSAEWOULDBLOCK, but the network operation went ahead. Whether the operation eventually succeeds or not, when the outcome has been determined, FD_CONNECT happens. The client should check the error code to determine whether the outcome was successful or failed.

26 2017/12/5

summary of events and conditions for asynchronous notification message.

Advanced Windows Network Programming

} FD_CLOSE: Only valid on connection-oriented sockets (for example, SOCK_STREAM)1.When WSAAsyncSelect called, if socket connection has been closed.2.After remote system initiated graceful close, when no data currently

available to receive (Be aware that, if data has been received and is waiting to be read when the remote system initiates a graceful close, the FD_CLOSE is not delivered until all pending data has been read).

3.After local system initiates graceful close with shutdown and remote system has responded with "End of Data" notification (for example, TCP FIN), when no data currently available to receive.

4.When remote system terminates connection (for example, sent TCP RST), and lParam will contain WSAECONNRESET error value.

27 2017/12/5

Note FD_CLOSE is not posted after closesocket is called.

Message-Driven Concurrent Server

Advanced Windows Network Programming28 2017/12/5

Summary

Advanced Windows Network Programming

} The WSAAsyncSelect model offers many advantages} foremost is the capability to handle many connections

simultaneously without much overhead, unlike the select model's requirement of setting up the fd_set structures.

} The disadvantages are } having to use a window if your application requires no

windows (such as a service or console application). } Also, having a single window procedure to service all the

events on thousands of socket handles can become a performance bottleneck (meaning this model doesn't scale very well).

29 2017/12/5

references

Advanced Windows Network Programming

} Programming With Microsoft Visual C++ NET 6th Ed. - George/Kruglinski Shepherd. 2002

} Network Programming for Microsoft Windows , 2nd Ed. -Anthony Jones, Jim Ohlund. 2002.

} MSDN: WSAAsyncSelect, WSAEventSelect Function} CUHK Ieg4180: Network Software Design and Programming} Drew Sikora, Programming with Asynchronous Sockets,

GameDev.net, 2/1/2001} http://www.sockets.com/err_lst1.htm#WSAEWOULDBLOCK} The C10K problem, http://www.kegel.com/c10k.html

30 2017/12/5