I believe that readers have basic understandings for Winsock's definition, system environment, and some Winsock Stack and Winsock applications. Next, I hope that I can introduce a simple WINSOCK network application design for readers. Based on the 46 Application Interface (API) defined by Winsock 1.1 specification, we will step by step by step to establish a pair of TCP Socket mainfast from the schema. In these two programs, Server will create Socket links, shutdown, and data delivery, etc., will use the "Asynchronous" function provided by Winsock; ). Since our focus is not in the MS Windows SDK program design, we will use the easiest way to display messages; the skills of the MS Windows program, please study the relevant books and articles by readers. Today, let's first take a look at the main connection (CONNECT) and close (close). Previously, the author has simply introduces the concept of the master from the architecture. Now we will explain the examples in life, readers will easily understand the description of the author later. We can assume that Server is like some of the services provided by the Telecom, such as "104 review" or "112 obstacles". (1) The Telecommunications Bureau first established a telephone switch, which is like a call socket () in the call set up a Socket. (2) The Telecommunications Bureau is then set to 104, just like we call the bind (), specify the Server's socket specified (bind) in a port. Of course, the Telecommunications Bureau must let users know this number; and our client program also knows the port used by Server, and there is a way to connect. (3) There will be some auto-service extensions under the 104 review table of the telecommunications office, but its number is limited, so sometimes you will not pass this number (busy line). Similarly, when we create a TCP's server socket, we will call the listen () in a letter to listen; the second parameter of listen () is the number of waiting queue, and the usual value is from 1 to 5. (In fact, the two are still a bit different.) (4) The user knows this 104 check-number service of the Telecom Bureau, and he can use a phone to dial to connect this service. This is why we client open an identical TCP Socket, then call the connect () to connect the port specified by Server. Of course, like the phone, if Waiting Queue is full, your connection will fail when it is unable to serve, or if Server does not provide this service, your connection will fail. (5) After receiving the call of this inquiry, the Tripline of the Telecommunications Bureau has turned to another extension, and the switchboard itself returns to the waiting state. Server Listening Socket is also the same, when you call the Accept () card, the Server's system creates a new Socket to serve this connection, and the original socket will return to the status of the listener.
(6) When you have finished the query, you can hang on the phone, and you will be offline. This is also true of Socket closing between Client and Server; however, this shuts down the offline action, can be shut down by the Client or Server. Some phone query systems are not the same? Next, we will look at how the main TCP socket is reached with these Winsock functions; and uses a function in the Winsock Stack in the WINSOCK Stack in the WINSOCK STACK in the Sockets. Only the programs of the program are listed in the article, please see the program of the appendix. [Server Establish Socket and enter the listening wait status] First, let's take a look at the Server end to create a TCP Socket and enable it to listen to the wait. In Figure 1. We can see the first call to the WSAStartup (). Description: WSAStartup (): Connect the first function with Winsock.dll. Format: int PASCAL FAR WSAStartup (WORD wVersionRequested, LPWSADATA lpWSAData); Parameter: wVersionRequested want to use the Windows Sockets API version lpWSAData pointer to the return value WSADATA information: Success - 0 defeat - WSASYSNOTREADY / WSAVERNOTSUPPORTED / WSAEINVAL Description: This letter "Must" is the first in the application call to the Windows Sockets DLL function, and only this function is successful after the call is successful, and the other Windows Sockets DLL can be called. This file also allows users to specify the Windows Sockets API version to use, and get some information from the designer. In the program, we have to use Winsock 1.1, so we have a section in the program: WSASTARTUP ((1 << 8) | 1), ((Word) ((Word) ((1 << 8) | 1) means that we want to use the Winsock "1.1" version, and WSADATA is used to store some information about this WinSock Stack. Let's call the socket () in a "TCP Socket" Socket (): Established Socket. Format: Socket Pascal Far Socket (INT AF, INT TYPE, INT Protocol); Parameters: AF currently only provides PF_INET (AF_INET) TYPE SOCKET (SOCK_STREAM, SOCK_DGRAM) Protocol Communication Agreement (if The user is not specified, set to 0) Passage: Success - Socket's identification code failed - INVALID_SOCKET (Call wsagetlasterror () Reason: This one is used to create a socket, and establish its site for this SOCKET The resources used. Socket can be a stream socket or a DataGram Socket. We have to build TCP socket, so our second parameter in the program is SOCK_STREAM, and we will open this Socket number in Listen_SD.
Listen_SD = Socket (PF_INET, SOCK_STREAM, 0) Next We want to specify a location and port to the SOCKET for Server, which client know which port will be connected? So we call bind () . Bind (): Specifies the local location of the Socket (AddRess). Format: Int Pascal Far Bind (Socket S, Const Struct Sockaddr Far * Name, Int Namelen); Paramese: s Socket Deficker Name Socket Address Name Dax Address Delivery Value: Success - 0 Failed - Socket_ERROR (Call WsagetLastError () can be learned to know: This one is specified to specify the local location and port gives an unnamed Socket. If the user does not at the address or port value, then he can set the location to INADDR_Addr_any, and port is 0; then Windows Sockets will automatically set it appropriate and port (1024 to 5000) ), The user can call GetSockName () when the SOCKET is really connected to the value. BIND () VOC wants to specify the order and port, this address must be the IP address of the machine in this program, so if the reader can set the address to INADDR_any when designing the program, so that the Winsock system will automatically The correct location is filled in. If you want to make the program only on a machine, set the location to the IP address of the machine. Since this end is a Server end, we must specify a port number to this Socket. Readers must pay attention to it, once the TCP Socket has selected a location and port, it is no longer able to call another bind to change its location or port. In the program we specify the port of the Server end to 7016, the address is set by the system. struct sockaddr_in sa; sa.sin_family = PF_INET; sa.sin_port = htons (7016); / * port number * / sa.sin_addr.s_addr = INADDR_ANY; / * address * / bind (listen_sd, (struct sockaddr far *) & sa, SIZEOF (SA)) We will use htons () in this group when specifying the Port number, mainly because the numerical read mode of each machine is different (the PC and UNIX system are different), so we use this letter to Host Order arrangements are converted into a NetWork ORDER arrangement; the same ground, we can also call NTOHS () to restore it. (Host Order machine is different, but NetWork Order is the same) (Htons is aimed for short values, and after the value of "with HOTNL and NTOHL), after we call Listen (), let this socket enter Monitor status. The TCP Socket of a Server side must accept the connection of the Client end after you have finished the list of Listen. Listen (): Sets Socket to the listening status, ready to be connected.
Format: Int Pascal Far Listen (Socket S, INT Backlog); Parameters: S Socket Identification Code Backlog Unspeakable to Complete Complete Connection Requirements The maximum number of transmitted values of the connection requirements of each other: Success - 0 failed - SOCKET_ERROR (Call WsageTlasterror () can be learned) Description: The user can use this file to set the socket to enter the listening state, and set up to how many of the ports that do not really complete the connection before the connection. (At present, the maximum value is limited to 5, the minimum is 1), we set backlog to 1. Listen (Listen_SD, 1) After the call is Listen, if the Client end is connected, the connection action of the Client side will succeed, but the Server end must call the Accept () in this time, it is formally completed the Server end. Connection action. But when can we know the client end to connect, while a timely call is ACCEPT? Here we have to use a good WSAAsyncSelect letter, turn the SOCKET of the Server to the Asynchronous mode, let the system actively to inform us that there is Client to connect. (Figure 1. This card is not drawn) WSAAsYNCselect (): Requires a Socket event (event) notify the user when an event occurs. Format: Int Pascal Far WSaasyncselect (socket s, hwnd hwnd, unsigned int wmsg, long levent); Parameters: s socket number HWND Action is completed, the message-receiving window Handle WMSG Remove the message of the window of the Window LEVENT application is interested in the network Road Event Passage Value: Success - 0 Failed - Socket_ERROR (Call Wsagetlasterror () Reasons Reasons) Description: This function is to request the user to request Windows Sockets DLL to send a socket with a network event when detecting a socket. The message to the user is designated by the user; the network event is set by the parameter Levent. Call this file to actively set the socket to a non-blocking mode. Levent's value can be the following "OR" portfolio: (see Winsock No. 1.1 88, 89) FD_READ, FD_WRITE, FD_OOB, FD_ACCEPT, FD_CONNECT, FD_CLOSE User If you call this one again for a socket, you will cancel it. The original settings for this socket. To cancel all settings to the socket, the value of the LEVEN must be set to 0. (Figure 2) WSAASYNCSELECT Funny Parameters and Application Relationship We ask the Winsock system to know when the client is coming to connect, send an async_event message to the hwnd this window; because we want to know only an Accept event, so we only Set the fd_accept.
WSAAsyncselect (Listen_SD, HWND, Async_Event, FD_ACCEPT) (Figure 3) Demoserv establishes socket on a Winking system and enters the listening status reader must pay attention to a point, the setting of WSaasyncselect is aimed at "a socket"; otherwise, only when you set up You will receive this message (async_event) when the event (FD_ACCEPT) of this socket (Listen_SD) occurs. If you open a lot of sockets, let each socket turn to Asynchronous mode, then you must set WSaAsyncselect to the "Every Socket". And if you want to cancel a Socket's Async event notification, then use WSaasyncselect this file; and the fourth parameter Levent must be set to 0. WSaasyncselect (s, hwnd, 0, 0) - Cancel all ASYNC event settings Here I want to tell you, call WSAAsyncSelect, while also changing this socket into a "non-blocking) mode. But at this time, this Socket does not simply use the ioctlsocket () to change it back to the "Blocking" mode. That is, the "non-blocking" mode changed by WSaasyncselect and IOCTLSocket is still different. If you want to change a SOCKET of "Asynchronous mode to" block "mode, you must call WSAAsyncSelect () to cancel all ASYNC events, and then turn it back to block the block. IOCTLSOCKET (): Controls the mode of the socket. Format: Int Pascal Far IOCTLSOCKET (Socket S, Long CMD, U_LONG FAR * Argp); Parameters: S Socket Identification Code CMD Directive Name Argp Number Parametric Passage Revitalization: Success - 0 Failed - Socket_ERROR (Call WsageTlasterror () Releaseable Cause) Description: This file is used to get or set the operation parameters of the socket. The instructions provided are: (See Winsock Item 1.1 35, 36) CMD's value: Fionbio - Switch Non-Blocking mode FionRead - Since Socket readable data (current In Buffer information) Quantity) Siocatmark - OOB Did it have been read because the SOCKET of our Server end is used in non-synchronous mode, and the FD_ACCEPT event is set, so when the Client side is connected to us, Winsock Stack will actively inform us; let's first Let's see how the Client side is connected to the Server end? [Client side actively establishes the connection] Client first is also a call wsastartup () in a copy to establish a relationship with the Winsock Stack; then call socket () to create a TCP Socket.
(Reader must use TCP Socket to connect to the Server's TCP Socket without using UDP socket; because the Sockets of the same agreement can be connected, TCP is different from the UDP) and the SOCKET of the Server end: Client The end of the socket can call the bind () in, specify the IP address and the PORT number; however, you can do not call Bind (), and the Winsock Stack is powered by the IP address and the PORT number (this action is in call The consNect () is complete by the Winsock system). Usually we don't call bind (), and by the system, you can call the getSockName () in the GetSockName () to check the system to help us set what IP and Port. In general, the system will automatically help us set between 1024 to 5000; and if the reader wants to set the port with BIND, it is best to 5000 or more numbers. Connect (): Requires a TCP Socket to the specified other party. Format: Int Pascal Far Connect (Socket S, Const Struct Sockaddr Far * Name, Int Namelen); Paramese: s Socket Identification Code Name This Socket wants to connect to the diamelelen name of Namelen Name: Success - 0 failed - Socket_ERROR (Call Wsagetlasterror () can be learned) Description: This file is used to establish a connection to the other party. If the specified object address is 0, the error value will be returned. When the connection is completed, the user can use this socket to do the use of transfer or reception. In our example, the client is to connect to the 7016 PORT listening to the Server on the machine, so we have the following frames. (Suppose our machine's IP has my_host_ip) strunt sockaddr_in sa; / * variable declaration * / sa.sin_family = PF_INET; / * Set the Server-end data to be connected * / sa.sin_port = htons (7016); sa.sin_addr. S_addr = htonl (my_host_ip); Connect (mysd, (Struct SockAddr Far *) & sa, sizeof (sa)) / * Establish connection * / [server-side connection] Since the SOCKET of our Server is set to "non-synchronization Mode ", and is for FD_ACCEPT events, so when the client is connected, the HWND of our Server end will receive a message from an async_event sent by Winsock Stack. (See the settings of WSAAsyncselect "At this time, we should use wsagetSelectEverror (LPARAM) to check if there is an error; and by WsagetSelectEvent (LPARAM) is what the event occurred (because the WSAAsYNCselect function can be set at the same time Many events, but only one message is used to represent) (here is of course FD_ACCEPT event); then call the related functions to handle this event.
So we call an Accept () in a function to create a connection to the Server end. Accept (): Accepts a Socket connection requirement to complete the connection of the Stream Socket. Format: Socket Pascal Far Accept (Scoket S, Struct Sockaddr Far * Addr, INT FAR * ADDRLEN); Parameters: s S socket identification code addr storage connection to the end of the address AddRlen Addr length passive: Success - new Socket identification code failed - INVALID_SOCKET (Call Wsagetlasterror () Reason: The application of the Server end calls this one-word to accept the Socket connection action required by the Client side; if the SOCKET of the Server is the Blocking mode, and no When people ask for a connection action, then this one will be held by Block; if it is a non-blocking mode, this file will reply immediately. ACCEPT () The reply value of a function is a new socket, which is not reusable to accept other connection requirements; but the SOCKET originally listened can still accept other people's connection requirements. The Server end of TCP Socket After calling accept (), it will return a new Socket number; and this new Socket number is a Socket that is truly communicating with the Client side. For example, we have established a TCP Socket with socket (), and this Socket number (system given) is 1, then we call Bind (), listen (), accept () is a stenet; After calling accept (), the return value is another Socket number (it is also a system), such as 3; then, the number 3; 3, not Socket 1; readers should not make mistakes. Our calls in the program are as follows; we can pass the second parameter to the value, know which IP address and the port number of the Port number are connected to our Server. Struct SockAddr_in sa; int sa_len = sizeof (sa); my_sd = accept (Listen_SD, (Struct Sockaddr Far *) & SA, & SA_LEN) When the Server end is completed, the main TCP Socket connection is really established. The server and client ends can also use this socket to send information to the other party or to the other party. (Related to the information of the information, let's talk about the next phase) (Figure 4) Demoserv and DemoCLNT After the connection is successful, the SOCKET connection is ended in Winking] Finally, let's take a look at how to end the socket connection. Socket is close and simple, and can be started first by any end of Server or Client, as long as CLOSESOCKET () can be called. To turn off the Socket of the listening state, it is also use this one. CloseSocket (): Close a socket.
Format: Int Pascal Far CloseSocket (Socket S); Parameters: S Socket Identification Code Passage Passage: Success - 0 Failed - Socket_ERROR (Call WsageTlasterror () Receptes: This one is used to close some Socket. If the user originally sets SO_DONTLINGER to the SOCKET to be turned off, it will reply immediately after calling this one, but this SOKCET has not been transferred after the data will continue after it will be closed. If the user originally set this socket as SO_Linger, there are two cases: (a) Timeout is set to 0, this Socket is reset immediately, and the not received or the unrecovered information is lost. (b) Timeout is not 0, it will be sent, or wait until TIMEOUT will really turn off. Before the end of the program, don't forget to call WSACleanup () to inform Winsock Stack; if you don't call this one, some resources may still be occupied by you and cannot be removed. WSACLEANUP (): End the use of Windows Sockets DLL. Format: INT Pascal Far WSacleanup (Void); Parameter: No passage: Success - 0 failed - Socket_ERROR () Call WsageTlasterror () Description: Application must call WSAStartup () before using the Windows Sockets DLL Register to Windows Sockets DLL; when the application is no longer necessary to use the Windows Sockets DLL, you must call this one to log out in order to release the resources it occupied. [Conclusion] This period will first introduce the connection and closure of the master from the architecture TCP Sockets, and will further describe how to send information, and other APIs. To learn how to write a Winsock program reader, you can study two prices of Demoserv and DemoClnt; maybe not writing very well, but I hope to bring a person who doesn't understand the Winsock program. Readers can also use an Anonymous FTP mode to the UPLOAD / WINKING directory of SEEDNET Taipei host tPTS1.SEED.NET.TW (139.175.1.10), winning the WINSOCK STACK's trial version of the Winking of Miss Chen Jianwei, to run Demoserv and DemoClnt These two programs and other lots of Winsock applications. (The official version Contained the SEEDNET Service Center, the new version of Winking has Windows Dial and PPP program, suitable for telephone call users to use seednet in the Windows environment; Winking also provides the use of the Ethernet environment.
) Simple Winsock Application Design (2) In the previous article, the author introduces you how to establish a TCP Socket for the Winsock Environment to establish the TCP Socket of the Lord Synual (CLIENT / Server; Today I Will continue to introduce you how to use TCP Socket to collect information, and explain the FD_READ and FD_WRITE events in the WSAAsyncselect library (the author has found that there are quite many people don't understand these two events). I believe that the readers already know that the TCP Socket is successfully established in the Client side call Connect, and the Server is called the Accept Function. After the connection is successful, the Client and Server can use this connection. Socket to transfer information to the other party, or collect the information sent by the other party. (Figure 1. TCP Socket Information Send) Before the introduction of information, the author first introduces TCP Socket and UDP Socket Features Time when sending data: Stream (TCP) Socket provides "two-way", "reliable", " Sill "," no revocation "information transmission. DataGram (UDP) Socket provides "two-way" communication, but there is no guarantee for "Sill", "Sill", "No Heavy Covers", etc., so users may receive no order, remarkable information, and even information It may also be omission during transmission. Since the UDP Socket is transmitted, it does not guarantee that the data can be fully delivered to the other party, so some of our commonly used applications (such as Telnet, Mail, FTP, News ..., etc.) use TCP Socket to ensure information Positiveness. (TCP and UDP package transfer agreement is not in our discussion, readers who want to know, please refer to related books) TCP and UDP sockets are two-way, so we use the same socket to do delivery and collection information. Action; General TCP Socket information is sent, and the two functions of call send () and RECV () are reached, while UDP Socket is used in sendto () and Recvfrom () two functions. However, TCP Socket can also be used in Sendto () and Recvfrom (), and UDP socket also can be used in Send () and RECV (), which will be explained later. Now let's take a look at the letter instructions for Send () and RECV () and go back to our previous approach. ◎ Send (): Use the connect-type Socket to transfer data. Format: Int Pascal Far Send (Socket S, Const Char Far * BUF, INT LEN, INT FLAGS); Parameters: S Socket Identification Code BUF Standby Quick Region Len BUF's Length Flags This Form is called Mode back value: Successful - Delivered Data Length Failed - Socket_ERROR (Call WsageTlasterror () Reason: This function applies to Connect DataGram or Stream Socket to transfer data. For the DataGram Socket, if the size of the DataGram exceeds the limit, any information will not be sent and the error value will be sent back.
For Stream Socket, in the Blocking mode, if the storage space in the transfer system is not stored in the transfer buffer, Send () will be held by Block until the data is delivered; if the socket is Set to a non-blocking mode, then how much information will be sent as the current Output Buffer space, will not be held by Block. Users should also pay attention to the Send () written execution completion, and does not mean that the information has been successfully sent to the other party, but in the Output Buffer of the system, waiting to be sent. The value of Flags can be set to 0 or MSG_DONTROUTE and MSG_OOB combination. (See Winsock 1.1 version 48) ◎ RECV (): Since Socket Receive Information. Format: Int Pascal Far Recv (Socket S, CHAR FAR * BUF, INT LEN, INT FLAGS); Parameters: s Socket Identification BUF Storage Received Temporal Len Buf Length Flags This Function is called Way back value: success - received the length of the data (if the other Socket is closed, it is 0) failed - Socket_ERROR (Call wsagetlasterror () can beware of the reason: this franchel with DataGram Socket or Stream Socket receives information. For Stream Socket, we can receive valid information in Input Buffer, but its quantity does not exceed the size of the LEN. If this Socket is set to SO_OOBINLINE, and the information of Out-of-Band is not read, only the data of Out-of-band is taken out. For the DataGram Socket, only the first DataGram is taken; if the DataGram is larger than the storage space provided by the user, only the space size of the space is taken out, and the reduced information will be lost and the wrong message will be replied. In addition, if the socket is Blocking mode, and there is no information in Input Buffer, RECV () reaches the block to any information; if the non-blocking mode, the Input Buffer has no information, it will reply to an error. The value of the parameter flags can be 0 or Msg_Peek, MSG_OOB combination; the MSG_peek represents the buffer provided to the user, but the information does not move from the system's Input Buffer; 0 indicates that the copy is removed. (Refer to Winsock 1.1 version 41) [Server's data collection and closing socket] In the previous period, we said that it is a SERVER for an Asynchronous mode; program we used to call the wsaasyncselect () in the list. And set the fd_accept event, so when the client is connected to us, the system will pass to us an Async_Event message (see the previous article content); we receive a message and judge the fd_accept event, so call accept () establish connection.
MY_SD = ACCEPT (Struct SockAddr Far *) & SA, & SA_LEN) We have successfully established a server-end connection with the Client side, and then create a new Socket (MY_SD) at this time after the call is connected to the accept (). Send information. Since we also want to use the asynchronous method, we must use the wsaasyncselect () to help create some events in the new Socket so that the Winsock Stack can actively inform us when the event occurs. Since our Server is passive acceptance of the request, then then answers, we set fd_read events; we also hope that Winsock Stack can actually notify us when you know Client Close Socket, so it also sets the fd_close event. (The reader must pay attention, the Socket number of our settings is the new Socket number (MY_SD, HWND, Async_Event, fd_read | fd, ask, async_event, fd_read | fd_close), which is the original listening state) WSaasyncselect (my_sd, hwnd, async_event, fd_read | fd_close), we are also Using HWND this window and async_event this message; in the forebel, the author told you that when you receive an Async_EVENT message, we can use WsageTSelectEvent (LPARAM) to determine which event (fd_read or fd_close) happens; so don't Will confuse. Then when will we receive a message from fd_read or fd_close event? [Fd_read event] We will receive the fd_read event to notify us to read the information: (1) Call the WSAAsyncselect function When setting the fd_read event on this socket, the Input Buffer is available. (2) Input buffer in the original system is empty, and when the system receives the information, it will notify us. (3) The user calls the RECV or Recvfrom function, reads the information from the Input Buffer, but does not read the data once, and then drive an FD_READ event, indicating that there is still information in the Input Buffer. Reader must pay attention: If we receive a message from the fd_read event notification, we deliberately don't call the RECV or Recvfrom to read the information, and then the system receives the information, and will notify us again, be sure to wait for us to call. After RECV or Recvfrom, it is possible to receive an event notification from FD_READ. [FD_CLOSE Event] When the system knows that the other party has closed Socket (received the FIN notification, and Hand-Shaking, and Hand-Shaking, we will receive the FD_CLOSE event notification so that we can also relatively Socket close up. The fd_close event will only happen to TCP Socket because it is Connection-Oriented; for the CONNECTIONLESS UDP Socket, even if fd_close is set, it will not work.
In the program, when the client is sent to a request, the system will notify us HWND window in an Async_EVENT message; we are using WsagetSelectEvent (LPARAM) and WsagetSelectEvent (LPARAM), after the fd_read event and check, call Recv () The function is charged for the information sent by the Client. Recv (WPARAM, & DATA, SIZEOF (DATA), in the previous article, also mentioned that the fd_xxxx event happened, when receiving the message, the parameter WPARAM when the window Handle is called is a Socket that occurred. The number, so the value of WPARAM here is the MY_SD this SOCKET number mentioned earlier. The fourth parameter of RECV () is set to 0, indicating that we have to read the information from the system's Input Buffer and remove it. After receiving the request, we have to reply the client, which is to send information to client; then we have to use Send (). Let's put the information in the data temporary area of the data, then call Send () to send it, and we use the same Socket for WPARAM (My_SD) to do the transmission action because it is two-way. Send (WPARAM, & DATA, STRLEN (DATA), 0) Server and Client Send data After a period of time (all the information is complete), if the client calls closesocket () Close the Socket on the end, then the system is known I will notify us of a message from a fd_close event. We can also call CloseSocket () to turn our socket. Socket; Of course, we can also call CloseSocket () to take the initiative to turn off our socket. [CLIENT NETATISTAL] The client of our example is a Blocking mode, so when the CONNECT () function is connected to the Server, it may be equal to the success; the connection is returned after returning, and no If the error occurs, the Client's TCP Socket connection is successful. At this time, we can use this successful Socket to send information. Since we don't have to set it as an Asynchronous mode, you don't have to call wsaasyncselect () to set events. The Client end is usually the first request to send request to the Server end, so we call send () to transfer this information. Our data is small, so it will not be lived by Send () written blasts; however, if you want to send the amount of information, you will wait for a while to return; It is necessary to wait for the data to put it until the system Output Buffer will return; this is because our Client's socket is blocking mode. If we use the Socket in the non-blocking mode, then the send () written will depend on the system's Output Buffer space, only to copy as much information to Output Buffer, then return, and tell the user how much information, Not necessarily, all materials are returned to Output Buffer. We will request to place in the Data data temporary area, then call Send () will be sent. After the data is sent, we call RECV () to wait for the reply of the Server.
Send (Mysd, Data, Strlen (Data), 0) RECV (MySD, & Data), 0) Since our client end is a Blocking mode, RECV () will always stay in Block until one of the following occurs Will return. (1) SERVER is sent. (At this point the RETURN value is the data length read) (2) The Server is turned off the opposite Socket. (At this time is 0) (3) The Client side calls WSACANCELBLOCKINGCALL () to cancel the recv () call. (At this time, the return value is a socket_error error. The error code 10004 wsaeintr is the same, after all the information is finished, we also call CloseSocket () to turn the socket. ◎ WSACANCELBLOCKINGCALL (): Cancel the blocking action currently in progress. Format: int Pascal Far WSAcancelBlockingCall (Void); Parameters: No passage: success - 0 failed - Socket_ERROR (Call WsageTlasterror () can beware of the reason) Description: This file is used to cancel the BLOCKING action in progress . The usual use is: (a) Blocking action is in progress, the application receives a message (Mouse, Keyboard, Timer et al.), Which can be called in the paragraph of the message. (b) Blocking action is in progress, while Windows Sockets calls the "BLOCIKING" function of the Windows Sockets, you can call this function in this function to cancel the blocking action. Users must pay attention to a WSAISBLOCKING () and WSAcAcLockingCall (), in addition to WSAisBlocking () and WSAcAll (), otherwise errors can be generated. In addition, if the blocking action is not accept () or select (), the socket may be undecided, and the user is best to call CloseSocket () to close the socket without any action to do it. (Figure 2.) Demoserv and DemoCLNT Send information on Winking on Winking (Figure 3.) Demoserv and DemoCLNT After the Scheme Wink is closed, the screen after closing the socket is over the data collection of TCP Socket, the author is then The reader introduces sendto () and recvfrom () two functions, as well as many people may easily make the FD_WRITE event. [Sendto and Recvfrom Versions] Generally, TCP Socket uses two functions of Send () and RECV (); the UDP socket is used for Sendto () and Recvfrom (). This is because the TCP is Connection-Oriented, and after the SOCKET real connection program is younger, you can start sending information. At this time, the system already knows the other party, so we don't have to specify where the information is to be sent.
UDP is ConnectionLess, and the two parties that send information do not build a real connection, so we need to use Sendto () and Recvfrom () to specify the following party and know who sent us to us. TCP Socket can also be sent by Sendto () and Recvfrom (), just at this time, the last two parameters of these two functions have no effect, it will be ignored by the system. UDP Socket If the Connect () is called to specify the location of the other party (this Connect does not really make a connection action with the other party, telling our own system saying that we only want to collect, send it) Then, Send () and RECV () can also be utilized to send information. ◎ Sendto (): Send data to the destination designated by the user. Format: Int Pascal Far Sendto (Socket S, Const Char Far * BUF, INT LEN, INT FLAGS, CONST STRUCKADDR FAR * TO, INT TOLEN); Parameters: s Socket Identification Code BUF Storage Information To send information LEN BUF's length Flags This function is called way to send the address to the site tolen to the size of the TOLEN TO: Success - the length of the data fails - Socket_ERROR (Call wsagetlasterror () can know why: this The function is suitable for DataGram or Stream Socket to transmit information to the specified address. For the DataGram Socket, if the size of the DataGram exceeds the limit, any information will not be sent and the error value will be sent back. For the Stream Socket, its effect is the same as send (); the value of parameters to and Tolen will be ignored by the system. If the storage space in the Transport system is not stored in these to be transferred, sendto () will be held by Block until the data is sent; unless the socket is set to a non-blocking mode. Users must also note that the sendto () letter execution is completed, does not mean that the information has been successfully sent to each other, but may still be in the system's Output Buffer. The value of Flags can be set to 0, MSG_DONTROUTE and MSG_OOB. (See Winsock No. 1.1 51) ◎ Recvfrom (): Read the data and store the location where the data source is stored. Format: Int Pascal Far Recvfrom (Socket S, CHAR FAR * BUF, INT LEN, INT FLAGS, INT FAR * ADDR FAR * from FROM, INT FAR * FROMLEN); Parameters: s Socket Identification Code BUF Storage Acquisition Zone LEN BUF Length Flags This Function This Function The way from the source from the source, the source of the source, the size of the source, the size of the source: Success - the length of the received data (if the other Socket is closed, 0) failed - Socket_ERROR (Call WsageTlasterror () Reasons for knowledge) Description: This file is used to read the data and record the location where the data source is recorded. For the DataGram Socket (UDP), a DataGram is read at a time; the STREAM Socket (TCP) is the same as the RECV (), the parameter from and fromlen is ignored by the system.
If Socket is a Blocking mode, and there is no information in Input Buffer, RECVFTOM () will be blocked to have any information; if it is a non-blocking mode, and INPUT BUFFER has no information, it will immediately return to the wrong mistake. [FD_WRITE Event] The author introduced the occurrence timing of the fd_read event in front, and now continues to introduce FD_WRITE this more confused event, because there is really a number of people in this incident unknown. From the literal, FD_WRITE should be required to inform us that a Socket now can call send () or sendto () to transfer information? The answer can be said "Yes", but it and fd_read have different places. In front, we know that after calling RECV (), if there is information that is not taken out in Input Buffer, the system will notify us of fd_read. Then if we call Send (), the system's Output Buffer still has space written, it will notify us of a fd_write, told us to continue the information? This answer is "negative"! The system will not notify us. The system will notify us of the message of the FD_WRITE event, only the following cases: (1) Call WSAAsyncSelect () When setting the fd_write event, Socket has been able to transfer information (TCP Scoket has been successfully connected, or the UDP socket has been established And currently Output Buffer still has space to be writable. (2) When the wsaasyncselect () is called to set the FD_WRITE event, the socket can not transmit information, but once the socket is successful, the FD_WRITE is received immediately. (3) When calling send () or sendto (), the system is informing the error, and the error code is 10035 WSAEWOULDBLOCK (call wsagetlasterror () knows this error), then the Output Buffer is already full, no longer writing Any information (at this point, the send () that is called more times will be failed. Once the system successfully fails to the other party, it will send an FD_WRITE to the user, and inform us to continue Information. In other words, the reader can continue to call Send () to transfer information as long as it returns the error 10035, and can always transfer the information; once send () returns an error 10035, then do not call send () transfer The information is required, and after receiving FD_WRITE, continue to transfer information. [Conclusion] In this article, the author introduces the time related to TCP Socket, sending methods, and fd_read, fd_write and other incidents; the readers are synthesizing the previous articles, should have been able to establish a pair The master from the architecture and uses TCP Socket to transmit information.
Next, the author will continue to introduce a letter about how to get online information, such as gethostname (), getSockName (), getPeername (), and synchronous network data library captured Frequency getXBYY (), WSaasyncGetxbyy (). The WINKING trial version mentioned herein can be obtained from the UPLOAD / WINKING directory of SEEDNET Taipei host tpts1.seed.net.tw (139.175.1.10), and the file is called WkDemo.exe; Winking provides Ethernet and PPP connection function, Suitable for general Ethernet networks, can also be used to call servo hosts on SEEDNET; □ Example Demoserv, DemoClnt, and some author writings WINSOCK program (including original program code) is stored in UPLOAD / WINKING / Under the jnlin directory; interested readers can get from an Anonymous FTP mode. Simple Winsock Application Design (3) In the previous two articles, the author introduced how to build the TCP socket from the Winsock environment, and how to use Socket to send information; Today, we will come to see one See how to use Winsock's functions to get some basic network information, including what the name of our own host is, the system actively specifies the IP address of our socket and Port Number, the other party connected by our socket is Who, how to find some host's IP address or name, as well as the port number used by some Well-KNown services (such as FTP, Telnet, etc.). Today, the exhibition we use is a program for test or teaching for WINSOCK 1.1. It is interested in seeing the readers who call 46 functions to "TPTS1." TPTS1. SEED.NET.TW "The" UPLOAD / WINKING / JNLIN "directory acquires the execution file and the original program code, and the file is named hello. *. Readers can also use Hello programs to simulate Server or Client programs to verify what we do. [How to know the Local host name we use] usually we will help us with this host yourself to set a name; in the program, we can also use a letter called gethostname () through Winsock. Come get this host name. ◎ gethostname (): Get the name of the local host used by the current user. Format: int Pascal Far getHostname (Char far * name, int namelen); Paramese: Name Used to store the size of the local HOST name Namelen Name Size Value: Success - 0 Failed - Socket_ERROR (Call WsageTlasterror () available Causes) Description: This file is used to get the name of Local Host.
In the program, the method of our call is as follows: gethostname ((Char Far *) HNAME, SIZEOF (HNAME)) Readers If you use Trumpet Winsock, you may know that there is nothing to set the local host name in the environmental setting of the Trumpet. The field, so when performing some public domain's Winsock Application (such as WS_PING, WINTALK), an error is generated when calling gethostname (); the solution is to add your host IP bit in the "Hosts" file in TRUMPET. Site and name, then call this file to generate an error. How to Item The System Active Specifies to our IP address and Port Number] In the previous article, the author used the TCP Socket of the Client to call the connection () function before the CONNECT () function is connected to the Server end. To specify the IP address used by the Client side, but in general, our Client end does not need to call bind () to specify a specific IP address and port number, but is handed on the system to help us. Socket Sets the IP address and the Port Number when the CONNECT () is called. But how do we know what IP address specified does IP address and port Number give us? This is to make a letter from getSockName (). ◎ getSockName (): Get the local location of the socket and Port Number data. Format: Int Pascal Far getSockName (Socket S, Struct Sockaddr Far * Name, INT FAR * NAMELEN); Parameters: s Socket Identification Code Name Store This Socket LOCAL address The length of the Namelen Name of Namelen Name: Success - 0 Failure - Socket_ERROR (Call Wsagetlasterror () can beware of this) Description: This file is used to obtain the local order information of the set location or connected Socket. If this Socket is set to INADDR_Addr_any, the correct location will be sent back after the actual establishment is successful. The method of the call in the program is: struct sockaddr_in sa; int sales = sizeof (sa); getSockName (SD, (SD, SD, (SD, (How to know who is connected to our Socket connection) Socket There is two ends, so relatable relative to getSockName (), Winsock also provides a getPeerName () in a V. Let us get the IP address with the other parties we connect to Port Number. ◎ getPeerName (): Gets the other party IP address of the connection success Socket and Port Number.
Format: Int Pascal Far getPeername (socket S, Struct SockAddr Far * Name, INT FAR * Namelen); Parameters: s Socket ID NAME Save the length of the tentative area of the other party IP address connected to this Socket connection Value: Success - 0 failed - Socket_ERROR (Call WsageTlasterror () can be learned: This one can be used to obtain the site data of the connected Socket. The call is as follows: struct sockaddr_in sa; int sales (SA); getPeername (SD, SD, SD, (SD, (STRUCKADDR FAR *) & SA, & SALEN) Now we still use Winking to be our Winsock Stack and use the tools it provides To observe whether the links and information of Sockets are correct. From Figure 1, we can see the window of Winking We set the name of this host is "Vincent", the IP address is "140.92.61.24". Let's take advantage of two Hello programs, one as a client (open by the right side), one as a server (minimizing the left side of the screen). The port number used by Server is "7016"; the client does not call bind () to specify Port Number, but is specified by the system when CONNECT () is called. We call gethostname (), the answer is "Vincent"; and the client call getSockName () gets its own IP address is "140.92.61.24", Port Number is "2110" (the author used to specify the system Port Number will be 1024 to 5000); then call getPeerName () Get the server-side IP address connected to the Client is "140.92.61.24" (because our client and server are in the same host), Port Number is "7016". Be bad! (The Sockets data that is connected to each other can also be observed by Winking Sockets' status window, which is the same as the result of our call figures) (Fig. 1) Using the Hello program to simulate Client and Server readers must pay attention to a point, getSockName () and getPeername The IP address acquired and Port Number is NetWork Byte Order, not Host Byte Order; if you want to turn to Host Byte Order, you must use both NTOHL () and NTOHS (). And we can see that the IP address is expressed in the "string", and it uses an inet_ntoa () letter; relatively, we can also use the inet_addr () to convert the string mode IP address to IN_ADDR format (Unsigned long). ◎ INT_NTOA (): Convert a network location into a "point format" string.
Format: CHAR FAR * PASCAL FAR inet_ntoa (struct in_addr in); Parameters: in a Structure Passage Value of the Internet Host Address: Success - a "Dotted) string failed - NULL Description: This card transfers an Internet address to the "ABCD" string format. ◎ INET_ADDR (): Converts the location of the string format into 32-bit yuan in_addr format. Format: unsigned long pascal far inet_addr (const char far * cp); Parameters: CP A "Dotted) string of" Dotted) strings on behalf of IP address: success - a Unsigned Long failed to represent Internet location - INADDR_NONE Description: This card translates a "point format" address to the applicable INTENET address. "Point format" strings can be one of the following four ways: (i) ABCD (II) ABC (III) AB (iv) A Figure 1 Hello, we write Local data to DISPMSG, then display Out; its usage is as follows: WSPrintf ((LPSTR) Dispmsg, "OK! Local IP =% S, Local Port =% D", INT_NTOA (Sa.sin_ADDR), NTOHS (Sa.sin_Port)); [Winsock Provided by Database Funny] Winsock also provides synchronous and non-synchronous network database functions; however, readers must know that the database refers to the database system such as Informix, Oracle, etc., but refers to the host IP. Address and Name, Name of Well-KNown and Socket type and Port Number, and protocol names and code. [Synchronous Database Function] First let's take a look at the first group: gethostbyName () and gethostbyaddr () Voices These two functions use let us get its IP address by a host name, or It is a name for its IP site. Generally we often use the name of the IP, because few people will remember the IP address of a machine, and the IP header of the TCP / IP package must also be recorded, receiving the host's IP Address, not the host name. ◎ getHostByname (): Use a host name to get the information of this host. Format: Struct Hostent Far * Pascal Far GeTHostByname (Const Char Far * Name); Parameters: Name Host Name Passage Value: Success - Indicator Failed to a Hostent Structure - NULL (Call WsageTlasterror () Reason: This file uses the HOST name to get other information of the host, such as the location of Host, alias, location, length, etc. ◎ gethostbyaddr (): Use a Host's IP address to get the information of this host.
Format: Struct Hostent Far * Pascal Far GethostbyAddr (Const Char Far * Addr, INT LEN, INT TYPE); Parameters: AddR NetWork Arrangement Line Len AddR Length TYPE PF_INET (AF_INET) Passage: Success - Pointing to a Hostent The structure of the structure failed - NULL (Call WsageTlasterror () can be known to the reason: This file is the use of IP location to get other information of the host, such as the name of Host, an alias, location, length, etc. The calls in the program are as follows: char host_name [30]; struct hostent far * htptr; / * Assuming Host_Name's value is set to the host name * / htptr = (Struct Hostent Far *) gethostByname (Struct Hostent Far *) GethOstbyName (char far *) host_name) struct in_addr Host_addr; Struct Hostent Far * htptr; / * Assuming Host_ADDR's value has set the IP address of the host of the host of the host that requires the information. * / htptr = (Struct Hostent FAR *) GethOstbyaddr (CHAR FAR *) & Host_ADDR, 4, PF_INET) In general, the winsock stack will look at the "Hosts" file in Local in the program. The main information; if not, it may be in the "Domain Name Service" inquiry, so when you call these two functions, sometimes wait. The child has gained a reply. If you want to make the program, you can put the usage of the usage host in the HOSTS file, so you don't have to query through DNS. Let's take a look at GetServbyName () and getServbyport (). Most readers should have used service applications such as Telnet, Mail, FTP, News; these applications, such as service names, port number used by servo, and Socket types; These information, we can use GetServbyName () or getServByport () to achieve without deliberately remember others. ◎ GetServByname (): Other information on the service in accordance with the Service Name and Communication Agreement (TCP / UDP). Format: Struct SERVENT * PASCAL FAR GETSERVBYNAME (Const Char Far * Name, Const Char Far * Proto); Parameters: Name Service Name Proto Communication Agreement Name Passage Value: Success - An indicator of the Server structure failed - NULL (Call Wsagetlasterror) Reasons for knowledge) Description: Use the service name and communication agreement to obtain the alias of the service, the PORT number used by the service. ◎ GetServByport (): Other information on the service is obtained in accordance with the Service (Service) PORT Number and Communication Agreement (TCP / UDP).
Format: Struct SERVENT * PASCAL FAR GETSERVBYPORT (INT Port, Const Char Far * Proto); Parameters: Port Services Port No. PROT NO: Success - A indicator of the Server structure failed - NULL (Call WsageTlasterror () Reasons for knowing: Use the port number and communication agreement to get the name, alias, etc. of the service. The usage methods in the program are: char serv_name [20]; Char Proto [10]; Struct Server Far * svptr; / * Assume SERV_NAME and PROTO to set the service name and communication protocol * / svptr = (Struct Server Far * ) GetServbyName (Char far *) serv_name, (char far *) proto) int serv_port; char proto [10]; Struct Server Far * svptr; / * Assume SERV_PORT and PROTO to set the port number and communication protocols used by the service * / svptr = (Struct Server Far *) GetServByport (HTONS (Serv_Port), (CHAR FAR *) Proto) Winsock environment, we can query the service information is stored in the "Services" file in LOCAL; this file All stored is Well-KNown service, basically we don't need to change it. Readers can also add their services to this file, but the service information you use is public, otherwise, others' Services files are not your service information. The final set of GetProtobyname () and getProtobynumber () is used to get some "protocol" materials, such as TCP, UDP, IGMP, etc. In general, we will not be used. ◎ getProtobyname (): Other information on the communication agreement in accordance with the name of the Communication Agreement (Protocol). Format: Struct Protoent Far * Pascal Far getProtobyname (Const Char Far * Name); Parameters: Name Communication Agreement Name Passage: Success - A indicator pointing to the Protoent structure failed - NULL (Call WsageTlasTerror () can beware of the reason: Use the name of the communication agreement to learn the alias, number and other information of the communication agreement. ◎ getProtobynumber (): Other information on the communication agreement in accordance with the number of communication agreements. Format: Struct Protoent Far * Pascal Far getProtobynumber (INT Number); Parameters: Number Return to the Host ORDER Arrangement Agreement Number: Successful - A indicator pointing to the Protoent structure failed - NULL (Call WsageTlasterror () can know the reason ) Description: Use the number of the communication protocol to know the name, alias, etc. of the communication agreement.
The call mode is as follows: struct protoent far * ptptr; char proto_name [20]; / * Suppose Proto_Name has first set up Agreement Name * / PTPTR = (Struct Protoent Far *) GetProtobyname ((Char Far *) Proto_name) Struct Protoent Far * ptptr; int proto_num; / * Suppose Proto_Num has first set up Agreement No. * / PTPTR = (Struct Protoent Far *) GetProtobynumber (Proto_num) Winsock Stack For the application call getProtobyname () and getProtobynumber () information, is taken Since the "Protocol" file of Local; if we don't need it, we don't have to change the content of this file. (Figure 2) Hello program call synchronous data library figures [Non-synchronous Database Function] Winsock 1.1 provides relatively six non-synchronous database functions for the six synchronization library functions described in front of the previous author. They are wsaasyncgethostbyname (), WSaasyncGetStbyAddr (), WSaasyncgetServbyName (), WSaasyncgetServbyport (), WSaasyncGetProtobyname (), WSaasyncgetProtobyname (), WSaasyncGetProtobynumber (). Since their data is the same as the synchronous database, the author only uses WSaasyncGethostByname () as an example, describes these non-synchronous functions, and tells you to readers, synchronous and non-synchronous library functions. From the literal, "non-synchronization" means that when we issued a problem, we will not pay immediately, and let us know when you wait until the system takes information. That's right, these non-synchronous database functions are like this. Like the WSaasyncselect (), we have to tell the Winsock system to accept the window and message code that accepts the notification message so that the system inform us. When we call the synchronous database, the return value is a temporary area that refers to the relative information, and this data temporary area is provided by the system; however, when the call is a non-synchronous database, we must prepare yourself The temporary area, and the location of this temporary area is used as a parameter, transmitted to the system so that the system is used to store the information. Readers must pay special attention to it: Before the system notification data is successful or fail, it will not delete the information temporary storage area of the system. Otherwise, when the system obtains information to write, the data area is no longer, will guide To a machine. In addition, the size of the data temporary area must be large enough enough to allow the system to store the obtained information. (The recommended value in Winsock Specifications is the provisional area of MaxGethoststruct 1024 Bytes size, the author thinks too big, 100 Byets is too enough to be too enough) When the non-synchronous database is a library, the received return is a code, this code The representative is the number of this call in the system; because it is not synchronized, we can call the wsacancelasynceness () in front of the answer to cancel the original call. This cancel action is to be utilized.
In addition, when we receive the result notification, the value of WPARAM is also this code; we can use WsageTasyncerror (LPARAM) to learn that the information is successful or failed; if the reason for failure is the original transmission of the original transmission area is too small. We can also use WSaasyncGetBuflen (LPARAM) to learn more than much temporary storage area. ◎ WSaasyncGethostByname (): Use a host name to get the information of this host. (Non-synchronous mode) format: Handle Pascal Far WSaasyncGethostByname (HWND HWND, UNSIGNED INT WMSG, Const Char Far * Name, Char Far * BUF, INT BUFLEN); Parameters: HWND Action is completed, the window Handle WMSG is transmitted back to the window Message Name Host Name BUF Standby Size BUFLEN BUF Size: Success - Handle Code Representing This Non-Synchronous Action Failed - 0 (Call Wsagetlasterror () Reason: This Function is Use the HOST name to get other information, such as the address, alias, location, length, etc. of Host. When the user calls this one, you must pass the window Handle, the message code, the storage address indicator of the information to receive information, and the like, where information can be notified to notify the window to use information. After calling this one, go back to the user's call point and pass back a Handle code, which can be used to distinguish this non-synchronous action or to cancel this non-synchronous action. When the data is obtained, the system will send a message to the user's designated window. ◎ WSACANCELASYNCREQUEST (): Cancel a unfinished non-synchronization requirement. Format: Int Pascal Far WsacanceLasyncRequest (Handle HasynctaskHandle); Parameters: HasynctaskHandle To cancel Task Handle Code Passage: Success - 0 Failed - Socket_ERROR (Call WsageTlasterror () Reason: This function is used to cancel it originally WSAAsyncGetxByy (), such as WSaasyncGetHostByName (), for example. The parameter HasyncTaskHandle is the code value passed back to the call wsaasyncgetxbyy (). If the non-synchronous requirements of the original call have been completed, it cannot be canceled. (Figure 3) Hello program calls the non-synchronous database of library functions [Conclusion] The author has introduced a large part of the Winsock application design, and I don't know if the reader has started to practice yourself write Winsock network. Is it? Next, the author will introduce the remaining functions. In addition to this author, you can practice some good online application software in addition to using someone else's designed online software, and people in the rest of the world know that Taiwan can also have people; Simple Winsock Application Design (4) The Linjun's writer has introduced the application of the application of the application provided by Winsock 1.1 in the previous article; the author also believes that readers have begun to use these APIs to develop their own networks. Application has been applied.
But maybe some readers still don't know what development tools do you have to develop Winsock 1.1 applications? Basically, the reader must of course have a compiler of Microsoft C or Borland C to compile your program; as for two files related to Winsock, one is "Winsock.h", the other is "Winsock .lib. These two files, readers can use Anonymous FTP to get from SEEDNET Taipei Host "TPTS1.SEED.NET.TW" to "UPLOAD / WINKING / WINSOCK_DOCUMENTS" directory. Then, the author should introduce the remaining various functions for you, including select (), setsockopt (), getSockopt (), as well as the BLOCIKINGHOK () and WSAunhookBlockingHook () and WSAunhookBlockingHook () to use when changing the system's Blocking Hook. [Special Select Function] If the reader of the UNIX BSD Socket program is written, you must know this Select () function is very easy. Because it can help you check if a set of sockets can read, write information, or to check if the socket is successful and the other party is successful, or whether the other party has closed the opposite socket. But is it so easy to use in the environment of Winsock 1.1 and MS Windows 3.x "Non-mandatory multi-workers"? When we use it, do you pay attention to what? Let the author will tell you now. ◎ SELECT (): Check if one or more sockets are readable, writable, or erroneous. Format: INT Pascal Far Select (int NFDS, FD_SET FAR * READFDS, FD_SET FAR * WRITEFDS, FD_SET FAR * EXCEPTFDS, Const Struct TimeVal Far * Timeout) Parameters: NFDS This parameter is here in this parameter. Sockets Writefds To be checked, Sockets ExceptFDs to be written To be checked if there is a wrong sockets timeout This letter is waiting for the time pass-up value: success - the total number of Sockets (if Timeout, 0) failed - Socket_ERROR (Call WsageTlasterror () can be learned) Description: The user can use this function to check if Sockets can be read, or have spaces to write, or have errors. Winsock 1.1, the SELECT () function () in the UNIX BSD, like the number of parameters and the data type, all of which have nfds, readfds, writefds, exceptfds, and timeout; however Winsock's NFDS is unpredictable, with this parameter, just in order to match the SELECT () function of UNIX BSD. As for readfds, WriteFDs, ExceptFDs is also a set of sets of sockets, so you can set up a number of Sockets's numbers in these three parameters at the same time; of course, these Sockets must be established by your application.
If you have any one of the Socket numbers that you set, you will fail () the call select () file (error code is 10038 wsaenotsock). Winsock also provides some macros to allow you to set or check the value of ReadFDs, WriteFDs, Exceptfds, including: (where s is representative, SET represented by readfds, writefds or exceptfds fd_zero (* SET) - Clean the value of the set of the set of FD_SET (S, * SET) - Add S to the SET FD_CLR (S, * SET) - Delete the SET from the SET to the FD_ISSET (S, * SET) - Check if S is existing in the SET readers to know the parameters readfds, WriteFDs, and ExceptFDs are all "called by value- result"; "Called By Value-Result" means that when we pass the parameters to the system, To first set the start value, and add the address of these parameters to the system; the system will use these values to do some operations or other purposes, and finally write the result back to the location of these parameters. Therefore, the values of these parameters may be different after incorporation, and they may be different; so readers must reset their values for these parameters each time before calling SELECT (). Suppose we have to check if Socket 1 and 2 can be used to transmit information, and whether socket 3 is readable; we don't plan to check if Sockets has an error, so ExceptFDS is set to NULL. The step is approximately as follows: fd_zero (& writefds); / * Clear WriteFDS * / fd_zero (& readfds); / * Clear readfds * / fd_set (1, & writefds); / * Add Socket 1 to WriteFDS * / FD_SET (2, & writefds); / * Add Socket 2 to WriteFDS * / fd_set (3, & readfds); / * Add Socket 3 to Readfds * / Select (..., & readfds, & writefds, null, ...) / * Call SELECT () Check event * / if (fd_isset (1, & writefds)) / * Check if socket 1 can be written * / send (1, data); / * Call send () must success * / if (fd_isset (2, & writefds)) / * Check if Socket 2 can write * / send (2, data); / * Call send () must success * / if (fd_isset (3, & readfds)) / * Check if Socket 2 is readable * / RECV (3, DATA ); / * Call RECV () must be successful * / select () "The fifth parameter" Timeout "of the function is to set the SELECT function to wait (block).说 说 说: (1) If Timeout is set to "Null", select () will continue to return to "at least" Socket event will be return, which is the same as other blocking functions.
Select (..., null) / * blocking * / (2) If the value of timeout is set to {0, 0} (seconds, microseconds), then SELECT () is after the check, no matter whether there is a socket event, Will immediately return, and will not stay. Timeout.tv_sec = timeout.tv_usec = 0; SELECT (..., & TIMEOUT) / * NON-Blocking * / (3) If Timout is set to {m, n}, then wait until at least a SOCKET event occurs, Or time to return (m second n microseconds) will retrn. Timeout.tv_sec = m; timeout.tv_usec = n; select (..., & timeout) / * Wait m seconds n microseconds * / on UNIX system, we usually use select () to do "polling" action, check Whether the event occurs; but in the MS Windows 3.x environment, it is always very careful, otherwise it may cause the entire Windows system to stop (because the CPU is occupied by your program); so be sure to use Note "Control release", otherwise, "Do not set Timeout to {0,0}" (because Timeout is set to {0,0}, the internal Winsock system may not call to the blocking hook function to release control) . The UNIX system is not similar to the "Time Sharing". (The so-called polling action refers to, you have a round ring in the program, and the actions that have been calling such a letter such as Select () SELECT () In addition to checking if the socket is read; For Non-Blocking Socket After calling connect (), you can use Select () WriteFDs to check if the connection has been successful (when this Non-Blocking Socket is set in WriteFDS, and is successful by SELECT); In addition, we can also use ReadFDS to check if the other party of the TCP socket is closed (when this socket is set in the readfDs, and is successful by Select, but calling RECV to collect data is Return 0). (Figure 1.) Several Different Different Usage of SELECT Functions The Unix system is not provided by the WSAAsYNCselect (), so we have to use the select () in a letter to do a polling action; but the Winsock system already sets it. WSAAsyncSelect () in the non-synchronous event, in order to make MS Windows "Message Driven" environment more efficient, readers should try to use WSaasyncSelect (), and use as a SELECT () method; this is why To define a maximum purpose of a WSaasyncSelect ().
[Change Socket Options "WINSOCK 1.1 also provides a setSockopt () file for Socket Options; because Options have a lot of projects, the author only says that the items that are more useful, the project, please The readers study themselves. ◎ setsockopt (): Sets Options for Socket. Format: int PASCAL FAR setsockopt (SOCKET s, int level, int optname, const char FAR * optval, int optlen) parameters: s Socket identifier level option level (SOL_SOCKET or IPPROTO_TCP go) set optname option name optval option provided Depending on the length of the Optlen Option Setting value: Success - 0 failed - Socket_ERROR (Call WsageTlasterror () Reason: This one is used to set some Options for Socket to change its actions. Options can be changed: (For details on Winsock Spec. 54) Option Type --------------------------------- -------------------- SO_BROADCAST BOOL SO_DEBUG BOOL SO_DONTLINGER BOOL SO_DONTROUTE BOOL SO_KEEPALIVE BOOL SO_LINGER struct linger FAR * SO_OOBINLINE BOOL SO_RCVBUF int SO_REUSEADDR BOOL SO_SNDBUF int TCP_NODELAY BOOL (1) SO_BROADCAST - - Suitable for UDP Socket. It is to allow UDP Socket "Broadcast" messages to the network. (2) SO_DONTLINGER - Suitable for TCP Socket. Its significance is to let Socket when calling CloseSocket () to shut down, and if you don't have to wait until the information is sent, you will call Return; CloseSocket () Function Return, the system will continue to send all the information. Only this Socket is really turned off. A TCP Socket is on the preset value of TCP Socket is Don't Linger. (3) SO_LINGER - Suitable for TCP Socket to set the linger value. If the value of linger is set, then when the CLOSESOCKET () is turned off, if there is information in the setput buffer of the socket, it will be ignored by the system without being sent. At this time, CloseSocket () will also Return immediately; if the linger value is set to n seconds, then the system will try to send the information in Output Buffer during this time, and the time is delivered to return Return from CloseSocket (). (4) SO_REUSEADDR - Allows Socket call bind () to set a already used location (including port number).
Let's take a linger value to set a socket as an example, see how to call setSockopt () in the program: Struct Linger linger; linger.l_onoff = 1; / * Open linger setting * / linger.l_linger = n; / * Set the linger time to n second * / setsockopt (s, sol_socket, so_linger, & linger, sizeof (struct linger)) relative place, if we want to know the current Option set value, then Using the getSockopt () in a letter. ◎ getSockopt (): A set value of a SOCKET is currently Option. Format: Int Pascal Far getSockOpt (socket s, int level, int ptname, char far * optval, int far * Optlen) Parameters: s S socket identifier LEVEL Option set LEVEL OPTNAME OPTION Name OptVal Option OPTLEN Option The length of the set value: Success - 0 failed - socket_error (Call WsageTlasterror () CAUSE: This file is used to get some Options settings of the current socket.
Similarly, we still get the value of a socket linger example, look at how the program should call getsockopt (): struct linger Linger; int opt_len = sizeof (struct linger); getsockopt (s, SOL_SOCKET, SO_LINGER, & Linger, & opt_len) [What is a blocking hook letter and how to set your own Blocking Hook Funny] What is the "Blocking Hook" card? Before interpreting, we must first analyze what is the internal extent of the blocks (such as Accept, Connect, Connect, etc.) provided by Winsock 1.1? Inside the Winsock Stack's Blocking, in addition to checking some conditions (such as whether the application has called WSAStartup ()? Is it correct? Wait? (;;) {/ * Execute a Blocking Hook Funny * / while (BlockingHook ()); / * Check if the user has already called WSACANCELBLOCKINGCALL ()? * / If (Operation_CanceLled ()) BREAK; / * Check the action is completed ? * / If (Operation_complete ()) Break;} Now we can clearly know that there are three important things in the rebound circle of the blocking, (1) Execute the Blocking Hook Function (2) Check if the user calls WSACANCELBLOCKINGCALL () Cancel the call for this blocking function? (3) Check if the action of this blocking function has been completed? Readers must pay attention, different Winsock Stack may not be the same in the order of doing these three things; some Winsock Stack may check if the block of blocking functions has been completed, then execute the blocking hook function; Blocking hook phones may not be called. When you will explain the key points of the Blocking Hook, readers can know why the author tells you in front of using a polling method. From the back ring, we can now know that the block of the blocking hook function is to let the system call before waiting for the blocking letter to complete it before, it is not used by our own app.
The Winsock system has a preset blocking hook function inside itself; now let's take a look at this preset Blocking Hook. Bool DefaultBlockingHook (void) {msg msg; bool ret; / * get the next message; if you have, you will handle it; if not, the control is released * / Ret = (Bool) PeekMessage (& MSG, NULL, 0, 0 , Pm_remove; if (re) {TranslateMessage (& MSG); DispatchMessage (& MSG);} Return Ret;} Oh! It is important in the blocking hook card to let the blocking letter can handle additional messages before waiting for action, or release the CPU control, so that other applications have an opportunity to perform. Now returning to the previous place, everyone thinks about it: If in the round circle of a Winsock Stack, check if the blocking function has been completed, then execute the blocking hook letter; then Is it possible to release the CPU control to make other programs? If we have a loop similar to the following, the entire Windows environment may live because of our program. For (;;) {FD_ZERO (& WriteFDS); fd_set (s, & writefds); timeout.tv_sec = timeout.tv_usec = 0; N = SELECT (64, NULL, & WRITEFDS, NULL, & TIMEOUT); if (n> 0) Break ; If (n == 0) / * timeout * / continue; ...} Send (s, data ...); In this back ring example, we originally want to use select () and polling to check Is there a space to write information in Output Buffer? If OUTPUT BUFFER is completely full, the select () is checked in the case, and Timeout is {0,0}, then immediately returnize 0, without calling to the blocking hook function to release The CPU control is given to other programs in the Windows environment (including the Protocol Stack) of Winsock, which is not assigned to the CPU time, Winsock Kernel can not send any information in Output Buffer; return from SELECT () in the ring. After, I will return to the front of the round ring, then call select (), immediately timeout ...; Windows system therefore live! What do you need to pay attention to in the Blocking Hook in addition to the problem of CPU control release? The big family will look at the round circle of the blocking letter in front of the blocking, the BLOCKING HOOK card is packaged in another infinite while ring.
If a Blocking hook version of the return value is never 0, then it will never be trapped in this infinity ring; so we must be very careful when designing your own Blocking Hook, you must be very careful. Know the use of the Blocking Hook Function and Design the BLOCKING HOOK VOC, how do we replace the original Blocking hook function? Then you have to use the wsasetblockinghook (). ◎ WsaseTBlockingHook (): Establish an application designated Blocking Hook. FarProc Pascal Far WsaseTBlockingHook (FarProc LPBLOCKFUNC) Number: LPBLOCKFUNC Points to the address of the location of the Blocking Hook Function to be installed: Refers to the description of the order of the previous blocking hook function: this Voice Let the user can set his own blocking hook and replace the original system preset. The setup will be executed when the application calls to the "Blocking" action. The only Winsock interface in the Blocking Hook in the BLOCKING Hook in the user can have WSAcanceLBLOCKINGCALL (). Suppose we own designed a Blocking Hook function called myblockinghook (), then the method registered with the Winsock program follows :( system in which _hInst this task on behalf Instance of) FARPROC lpmybkhook = NULL; lpmybkhook = MakeProcInstance ((FARPROC) myblockinghook , _HINST); WsaseTBlockingHook ((FARPROC) lpmybkhook; (Figure 2.) Setting your own Blocking Hook Funcy We can use WSAunhookBlockingHook () in setting up your own Blocking Hook () Function, to cancel us The BLOCIKING HOOK function is changed back to the Blocking Hook in the original system. ◎ WSAUNHOKBLOCKINGHOK (): Restore system preset Blocking Hook Functions. Format: Int Pascal Far WSAUNHOKBLOCKINGHOK (VOID) Number: No pass-up value: Success - 0 failed - socket_error (Call Wsagetlasterror () can beware of the reason) Reply to the original preset Blocking Hook in the system. Finally, the author will explain that the Blocking hook function set by an application will only be used by this application; other applications do not perform it to the Blocking Hook in your setting. In addition, if it is necessary, it is best not to change the BLOCKING HOOK function of the system anywhere; because you are not designed, the entire Windows environment may end.
(Figure 3.) When using its own Blocking hook, the precaution [Conclusion] The four "Winsock Application Design" is over; the author has designed Winsock.dll in addition to the Winsock API. Experience is shared with readers; I hope these issues have a little help for the readers who want to develop online applications in the Winsock 1.1 environment. thank you all. From: zhangwe.bbs@bbs.net.tsinghua.edu.cn Date: WED, 22 Jan 1997 11:43:10 0800 (CST) Message-ID: <199701220343.la22158@bbs.net.tsinghua.edu.cn > X-Authentication-Warning: bbs.net.tsinghua.edu.cn: bbsroot set sender to zhangwe.bbs@bbs.net.tsinghua.edu.cn using -f reply-to: zhangwe.bbs@bbs.net.tsinghua . teu.cn to: fz868@public.zz.hy.cn Subject: Winsock API Daquan (2) - Alex Squiring (forward) X-Forwarded-by: Zhangwe (Lele) X-Disclaimer: BBS Shuimu Tsinghua Station The content of this letter is not responsible. PRECEDENCE: TEXT Content-length: 12357 Posted by: Godman on 'Internet' Title: Winsock API Daquan 2/2 (Chinese) Date: Mon Sep 25 09:26:11 1995 [Microsoft Windows -Specific Extensions] (1) WSAAsyncGethOSTBYADDR (): Utilize the location of a Host to get the information. (Non-synchronous mode) Format: Handle Pascal Far WSaasyncGethosTbyAddr (HWND HWND, Unsigned Int WMSG, Const Char Far * Addr, Int Len, Int Type, Char Far * BUF, INT BUFLEN); Numeral: HWND Action is completed, accept News window Handle WMSG Removes Window Message AddR Network Arrangement Line Len AddR Length Type Pf_Inet (AF_INET) BUF Started HOSTENT Data Regional BUF Size Passage: Success - Handle Failed to the ASYNC Action - 0 (Call WsageTlasterror () can beware of the reason) Description: This file uses the location to get other information of Host, such as the name of Host, alias, location, length, etc.
When the user calls this one, you must pass the window handle, information code, information of the information to receive the information, and the like, where information can be notified when it can be notified to use the information. When you call this one, you will go back to the user's call point and pass back a handle, which can be used to distinguish this non-synchronous action or to cancel this non-synchronous action. When the data is acquired, a message will be sent to the window specified by the user. (2) WSAAsyncGethostByname (): Use the name of a Host to get the information of the Host. (Non-synchronous mode) Format: Handle Pascal Far WSaasyncgetHostByname (HWND HWND, UNSIGNED INT WMSG, Const Char Far * Name, Char Far * BUF, INT BUFLEN); Number: After HWND action is completed, the window accepts the message Handle WMSG biography Back to Window Message Name Host Name BUF Standby BUF Size BUF Value: Success - The Handle Failed to the ASYNC Action - 0 (Call WsageTlasterror () Recept: This function is to use Host Name to get other information, such as Host's address, alias, location, length, etc. When the user calls this one, you must pass the window handle, information code, information of the information to receive the information, and the like, where information can be notified when it can be notified to use the information. After calling this one, go back to the user's call point and pass back a handle, which can be used to distinguish this non-synchronous action or to cancel this non-synchronous action. When the data is acquired, a message will be sent to the window specified by the user. (3) WSAAsyncGetProtobyname (): Other information on the communication agreement in accordance with the name of the communication agreement. (Non-synchronous mode) Format: Handle Pascal Far WSaasyncGetProtobyname (HWND HWND, UNSIGNED INT WMSG, Const Char Far * Name, Char Far * BUF, INT BUFLEN); Number: After HWND action is complete, accept the message Handle WMSG Back to Window Message Name Communication Agreement Name BUF Started the size of the area BUFLEN BUF: Success - the Handle failed to represent this Async action - 0 (Call WsageTlasterror () Reason: Use the name of the communication agreement To learn the alias, numbers such as the communication agreement. When the user calls this one, you must pass the window handle, information code, information of the information to receive the information, and the like, where information can be notified when it can be notified to use the information.