Contenu connexe
Similaire à WinSock Asynchronous Input/Output
Similaire à WinSock Asynchronous Input/Output (20)
WinSock Asynchronous Input/Output
- 1. WinSock Asynchronous
Input/Output
ECE 4564: Network Application Design
Scott F. Midkiff
Bradley Department of Electrical
and Computer Engineering
Virginia Polytechnic Institute and State University
Topics
! Need for specialized WinSock calls
! Blocking and message-driven architecture
! Asynchronous calls
" Message-based
" Event-based
" Asynchronous TCP ECHO server example
" Database calls
! WinSock version checking
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 2
© 1998-2002, Scott F. Midkiff
- 2. WinSock ≠ BSD UNIX Sockets
! WinSock 1.1 and 2.2 “core” calls are based
on BSD UNIX Sockets model
" Builds on existing knowledge base -- BSD UNIX
Sockets widely used by network programmers
" Simplifies porting of applications from UNIX to
Microsoft Windows
! Usual socket calls may not be the best to
use in Windows, especially for windowed
applications
" Blocking can cause problems for
message-driven operating system
" May not take full advantage of Windows
advanced I/O features
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 3
Message-Driven Architecture (1)
! Microsoft Windows is message-driven
" System indicates “events” by providing a
message to a program
" The program responds to the message
" The response may lead to new messages being
sent at a later time or new messages may occur
because of user actions
! Messages indicate different system events
" User interface action
" I/O completion
" System call completion
" Error conditions
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 4
© 1998-2002, Scott F. Midkiff
- 3. Message-Driven Architecture (2)
! Windows programs must check messages
and will be unresponsive if messages are
not checked
" Not an issue for console applications
! Multitasking scheme determines how
processes share the processor -- and when
messages are checked
" 16-bit Windows (3.1 and 3.11) uses cooperative
multitasking
" 32-bit Windows (95, 98, ME, NT, 2000, and XP)
uses preemptive multitasking
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 5
Cooperative Multitasking
! Processes must check
for messages to keep
system “alive” Message
! Blocked calls block the Queue
entire system
Dispatch
Process Process ... Process
GetMessage()
PeekMessage()
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 6
© 1998-2002, Scott F. Midkiff
- 4. Preemptive Multitasking (1)
... Message
Queues
Dispatch Dispatch
Thread Thread
GetMessage() GetMessage()
PeekMessage() PeekMessage()
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 7
Preemptive Multitasking (2)
! Each thread has a message queue
! Operating system preempts threads so that
a single blocked thread will not block other
threads
! Blocking can make an application
unresponsive and should be avoided, at
least in user interface threads
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 8
© 1998-2002, Scott F. Midkiff
- 5. Messages and Application Code (1)
! A Windows application defines a procedure
to handle messages for a window
! Example: dialog process or DialogProc()
" hwndDlg identifies where to to send messages
" uMsg, with wParam and lParam, define message
BOOL CALLBACK DialogProc(
HWND hwndDlg, // handle to dialog box
UINT uMsg, // message
WPARAM wParam, // 1st message parameter
LPARAM lParam // 2nd message parameter
);
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 9
Messages and Application Code (2)
! Dialog procedure processes messages
switch(uMsg)
{
case WM_INITDIALOG:
// process initialization message
case WM_COMMAND:
// process user interface message
case SM_EVENT:
// process asynchronous WinSock event
…
}
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 10
© 1998-2002, Scott F. Midkiff
- 6. Non-Blocking WinSock Calls
! To prevent blocking in an application
thread, use non-blocking WinSock calls
! Two approaches
" Non-blocking sockets
# ioctlsocket() to make socket non-blocking
# select() to determine readiness of socket
# Largely portable to UNIX
" Asynchronous calls (preferred method)
# Asynchronous call returns immediately
# Completion is indicated to application (three
notification methods)
# Windows-specific (WSA prefix for function
names)
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 11
Notification Methods (1)
! Three notification methods
$ Message-driven
% Event-driven
& Callback routine
! Message-driven notification
" Window handle passed to WSAAsyncSelect() or
other asynchronous call
" Message is sent to indicated window procedure
upon completion
" Requires a windowed application
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 12
© 1998-2002, Scott F. Midkiff
- 7. Notification Methods (2)
! Event-driven notification
" Event handle passed to WSAEventSelect() or
other asynchronous call
" Event is signaled, application must check
" Can be used with any application
! Callback routine
" Pointer to callback procedure is passed to call
such as WSASend() or WSARecv()
" WinSock “calls back” at indicated procedure
when action is completed
" Can be used with any application
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 13
WSAAsyncSelect() (1)
! Makes socket non-blocking
" No need to call ioctlsocket()
! Allows application to tell WinSock that
messages should be sent for certain events
" When a connection is established
" When data is ready for receiving from socket
" When data can be sent to socket (following a
situation when data cannot be sent)
" When socket is closed by peer
" When out-of-band data is received
" When socket or socket group quality of service
(QoS) changes
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 14
© 1998-2002, Scott F. Midkiff
- 8. WSAAsyncSelect() (2)
! Note that one message is created for any
event — cannot have different messages
" wParam is the socket descriptor
" lParam contains event code and error code
# WSAGETSELECTEVENT(lParam)
# WSAGETSELECTERROR(lParam)
int WSAAsyncSelect (
SOCKET s, // socket
HWND hWnd, // window for messages
unsigned int wMsg, // message number
long lEvent // types of events
);
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 15
WSAAsyncSelect() (3)
! Example call
" Define SM_EVENT as the message to be sent to
window with handle hWnd
" Check for connect, close, read, and write events
on socket sock
#define SM_EVENT WM_USER + 1
cc = WSAAsyncSelect (
sock,
hWnd,
SM_EVENT,
FD_CONNECT| FD_CLOSE | FD_READ | FD_WRITE
);
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 16
© 1998-2002, Scott F. Midkiff
- 9. WSAEventSelect() (1)
! Note that WSAAsyncSelect() requires that
the application have a window to receive
messages
! Windows are not always suitable
" Console applications are simpler to design
" Long-running servers
! WSAEventSelect() allows asynchronous
notifications to be provided to applications,
which may or may not have a window
" Sets an event object instead of posting a
message to a window handle
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 17
WSAEventSelect() (2)
! Makes socket non-blocking
! Allows application to specify event types for
which the event will be set
" Same set as for WSAAsyncSelect()
" Event bit mask
int WSAEventSelect (
SOCKET s, // socket
WSAEVENT hEventObject, // event handle
long lNetworkEvents // event bit mask
);
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 18
© 1998-2002, Scott F. Midkiff
- 10. Asynchronous Echo: Overview
! TCP ECHO server with asynchronous event
notification (aechod.cpp)
! Similar in concept to singly-threaded
concurrent TCP ECHO server
(tcpmechod.cpp)
! Two classes of sockets
" Master socket (index = 0)
# Monitor when ready for accept (FD_ACCEPT)
" Sockets for connections to clients (index > 0)
# Monitor when ready for read or write or when
a close occurs (FD_READ | FD_WRITE |
FD_CLOSE)
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 19
Asynchronous Echo: Calls (1)
! WSACreateEvent()
" Used to create an event object
" One event object per socket
" Events[NumSock] = WSACreateEvent();
! WSAEventSelect()
" Used to indicate monitored event types
" Master socket:
WSAEventSelect(temp_sock, Events[0],
FD_ACCEPT);
" Per connection socket:
WSAEventSelect(temp_sock, Events[NumSock],
FD_READ | FD_WRITE | FD_CLOSE);
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 20
© 1998-2002, Scott F. Midkiff
- 11. Asynchronous Echo: Calls (2)
! WaitForMultipleEvents()
" Used to wait for any one event to be signaled
" SigEvent = WSAWaitForMultipleEvents(
NumSocks, Events, FALSE, WSA_INFINITE,
FALSE );
DWORD WSAWaitForMultipleEvents(
DWORD cEvents, // number of events
const WSAEVENT FAR *lphEvents, // array
BOOL fWaitAll, // wait for all events
DWORD dwTimeOUT, // time out value
BOOL fAlertable // make alertable
);
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 21
Asynchronous Echo: Calls (3)
! WSAEnumNetworkEvents()
" Determine triggering event, e.g. FD_READ
int WSAEnumNetworkEvents (
SOCKET s,
WSAEVENT hEventObject,
LPWSANETWORKEVENTS lpNetworkEvents
);
typedef struct _WSANETWORKEVENTS {
long lNetworkEvents;
int iErrorCodes[FD_MAX_EVENTS];
}
WSANETWORKEVENTS, FAR * LPWSANETWORKEVENTS;
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 22
© 1998-2002, Scott F. Midkiff
- 12. Asynchronous Echo: Calls (4)
! WSACloseEvent()
" Releases event object
" WSACloseEvent(Events[EventNum]);
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 23
Asynchronous Echo: Data Structures
! Array of event handles
" WSAEVENT Events[MAXSOCKS];
! Array of socket information structures
struct info {
SOCKET sock;
int state;
char buf[BUFSIZE];
char * bufptr;
int buflen;
};
struct info * Socks[MAXSOCKS];
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 24
© 1998-2002, Scott F. Midkiff
- 13. Asynchronous Echo: Operation
FD_WRITE && block FD_WRITE && block
FD_READ && !block
awaiting
FD_ACCEPT
recv(), send()
accept()
FD_READ && block
send()
recv(), send()
READING WRITING
FD_WRITE && !block
send()
FD_CLOSE
FD_CLOSE
cleanup CLOSING
closed
send()
FD_WRITE && !block
send(), cleanup
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 25
Asynchronous Database Functions
! Asynchronous version of getXbyY() calls
" WSAGetHostByAddr()
" WSAGetHostByName()
" WSAGetProtoByNumber()
" WSAGetProtoByName()
" WSAGetServByPort()
" WSAGetServByName()
! Most important are WSAGetHostByAddr()
and WSAGetHostByName() because of long
potential delays
! Special call to cancel outstanding request
" WSACancelAsyncRequest()
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 26
© 1998-2002, Scott F. Midkiff
- 14. WSAAsyncGetHostByName()
! Identify window and message as in
WSAAsyncSelect()
! Provide host name and return buffer
" Buffer must be large enough for all information
since no information is stored by WinSock
HANDLE WSAAsyncGetHostByName (
HWND hWnd, // window for msg
unsigned int wMsg, // message id
const char FAR * name, // host name
char FAR * buf, // return info
int buflen // buffer length
);
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 27
WinSock Version Checking (1)
! WSAStartup()
" Version requested is an input parameter
" Returned LPWSADATA structure indicates
# Version that WinSock expects application to
use
# Highest version supported by this WinSock
! For example, if version 1.1 is requested from
WinSock 2.2
" Version requested is 1.1
" Version expected (wVersion) is 1.1
" Highest version supported (wHighVersion) is 2.2
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 28
© 1998-2002, Scott F. Midkiff
- 15. WinSock Version Checking (2)
Results from WSAStartup()
Version Version
Running Requested wVersion wHighVersion
1.1 1.0 WSAVERNOTSUPPORTED*
1.1 1.1 1.1 1.1
1.1 2.0 1.1 1.1
2.0 1.1 1.1 2.0
2.0 2.2 2.0 2.0
2.2 2.0 2.0 2.2
2.2 2.2 2.2 2.2
* Error return from WSAStartup()
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 29
WinSock Version Checking (3)
! A robust application should ensure that
requested version is supported
if(WSAStartup(wVersionReq, &wsaData)!= 0){
// Check for error return
}
else if (wsaData.wVersion != wVersionReq) {
// Version not supported
}
else {
// Version is supported
}
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 30
© 1998-2002, Scott F. Midkiff
- 16. You should now be able to …
! Indicate the benefit of non-blocking calls in
a message-driven operating system such as
Microsoft Windows
! Describe basic mechanisms for notification
including messages and events
! Analyze and design simple programs using
asynchronous sockets with event-based
notification
! Describe the asynchronous database calls
! Analyze and design code that verifies
WinSock versions
ECE 4564: Network Application Design (10/6/2002) WinSock Asynchronous I/O - 31
© 1998-2002, Scott F. Midkiff