Windows Sockets Specification and Applications - Windows Network Programming Interface ********************************************************* ************************ Copyright Information This book author retains all copyrights. No commercial reprint or replication. Reprinted and replication of non-profit nature must not modify the contents of the article and keep this paragraph. Copyright (c) 1995-1996 by Shi Wei, Li Wei, Qin Ying ALL RIGHT RESERVED ******************************************** ********************************* The content of the content is adapted to the trend of Windows, Internet, and computer network popularity. Introduced a set of specification for network programming under Windows - Windows Sockets. This set of specification is a widely used, open, supported network programming interface, which supports multiple protocols. From version 1.0 from 1995 to version 2.0.8, it has become a factual standard for Windows network programming under the full support of Intel, Microsoft, Sun, SGI, Informix, Novell, etc. In order to make readers fully understand and apply this set of specifications, this book not only has a more detailed introduction to Windows Sockets 1.1 and 2.0 norms, but also combines the actual work of the author, which gives examples of programs with practical application value. The contents of the book include: Windows Sockets Specification 1.1 and 2.0.8 introduction; Windows Sockets Network Programming Guide and Specific Applications; Windows Sockets Specification 1.1 and 2.0.8 library function reference, etc. This book system is complete, smooth text, can be used to engage in engineering and technicians and teachers and students of online application development. The author declares that due to the time of success. This book is not existing many mistakes and improper, so the author I sincerely hope that readers can make valuable comments on this book (including supplement new application examples and content) so that we can further modify this book. We will respect the copyright of the corresponding revision. The author also sincerely hopes that in our efforts and readers, this book can become a system of Windows Sockets programming, and accurate free Chinese reference books, providing help from the readers to network programming under Windows. Author contact: Shi Wei: Shanghai Jiaotong University 94032 class (200030) Email: Weishi@fudan.ihep.ac.cn Li Wei: Shanghai Jiaotong University Automation (200030) Email: Blee.bbs@captain.Net.tsinghua.edu Qin Ying: Shanghai Jiaotong University 94033A Class (200030) Email: Fluke.bbs@captain.Net.tsinghua.edu.cn Author I hope that readers who get this book can inform us in any way. So we can master the application of this book. And, readers, readers should not be distributed at other FTP sites, thank you for your cooperation. Surprising Scriptures May 20, 1996 Preface Today, the world is in the information age, computer and communication networks are the so-called "information infrastructure" in this era. Netization is one of the important development trends in the 1990s of the computer technology. At present, the new development of computer networks is: all-in-road networks and exotic networks have a big breakthrough.
The TCP / IP protocol reflects its powerful vitality in the internet interconnection, which is based on the Internet is currently the largest computer network network in the world. By the end of 1991, there are more than 5,000 countries in the world. The network is connected to the Internet, which includes 300,000 hosts of thousands of organizations, millions of users. The popularity of computer networks should be the widespread application of Windows, and now more than 420 million users have used different versions of Windows. Since the official launch of Windows 95, on August 24, 1995, sales in a short week has exceeded 1 million, some retail stores have to open the door in the middle of the night to meet the rolling snappers. This shows that Windows based on user-friendly graphics interface has been widely recognized by users, and will continue to be a factual operating system standard on a personal computer platform. So research and development of network programming technology under Windows has universal application value. In various network programming interfaces under Windows, Windows Sockets stand out, getting more and more important, because the Windows Sockets specification is a set of open, supporting a network programming interface under Windows of multiple protocols. From version 1.0 from 1995 to version 2.0.8, it has become a factual standard for Windows network programming under the full support of Intel, Microsoft, Sun, SGI, Informix, Novell, etc. During application development in the use of the Windows Sockets specification, it is found that this information is rare, especially the lack of comprehensive and practical monographs. In order to enable the majority of users to fully understand and apply this set of specifications, we have written this book. This book not only has a more detailed introduction to Windows Sockets 1.1 and 2.0 norms, but also combines the actual work of the author, which gives examples of programs with practical application value. I hope that it can make the role of the windows sockets in the domestic promotion and application of the country. Readers are in the process of reading this book, and if they can help and guide their learning work, the author's biggest wish. Due to the time urgent, the author is limited, the mistakes in the book are inevitable, and the readers will be enlightened. This book is completed by Shi Wei, Li Wei, Qin Ying, including the first, second, fourth, six chapters and 5.2 sessions by Shi Wei; seventh chapter, 5.1, 3.4, Li Tei, section 5.3 3.1-3.3 Section is written by Qin Ying. During the preparation of this book, I have been strongly supported by Mr. Huihui, Shanghai Jiaotong University, and provides some of the latest information, and I would like to express my heartfelt gratitude.
Editor's first chapter in September 1995, Chapter 1 Introduction 1.1 What is Windows Sockets specification? 1.2 Bekeley socket 1.3 Microsoft Windows and extension 1.5 This specification 1.5 Once modified 1.5.1 Windows SOCKETS 1.0 1.5.2 Windows Sockets 1.1 Chapter 2 Using Windows Sockets 1.1 Programming 2.1 Windows Sockets Titting Stack Installation Check 2.2 Sets 2.2.1 Basic Concept 2.2.2 Client / Server Model 2.2.3 External Data 2.2.4 Broadcast 2.3 Byte order 2.4 socket property option 2.5 Database file 2.6 Different 2.6.1 socket data types and error values 2.6.2 select () function and fd_ * macro 2.6.3 Error code - erno, h_errno, Wsagetlasterror () 2.6.4 Pointer 2.6.5 Renamed Functions 2.6.5.1 Close () and CloseSocket () 2.6.5.2 IOCTL () and iOOCTLSocket () 2.6.6 Block routines and EinProgress macro 2.6.7 Windows sockets supported Number of sockets 2.6.8 Header 2.6.9 API call fails return value 2.6.10 Original set interface 2.7 Windows Sockets in multithreaded Windows Version Chapter 3 Windows Sockets 1.1 Application Example 3.1 Interface Network Programming Principle 3.2 Windows Sockets Programming 3.3 Windows Sockets and UNIX Set Interface Programming Example 3.3.1 Server Introduction 3.3.2 Contecing 3.3.3 Source Program List 3.4 Another Exquisical Application Instance -
WSHOUT 3.4.1 Source Catalog 3.4.2 Program Logic Structure 3.4.3 Source Prices List and Note 3.4.3.1 WSHOUT.C List 3.4.3.2 WSHOUT.H List 3.4.3.4 WSHOUT.RC List 3.4.4 Ushout.c List 3.4 .3.5 ulisten.c List 3.4.3.6 TSHOUT.C List 3.4.3.7 Tlisten.c List 3.4.3.8 Errno.c List 3.4.3.9 Resolve.c List Chapter 4 Windows Socket 1.1 Library Function Overview 4.1 Sets of interface functions 4.1.1 Blocking / Non-Blocking and Data Volatility 4.2 Database Functions 4.3 For Microsoft Windows Extended Functions 4.3.1 Asynchronous Selection Mechanism 4.3.2 Asynchronous Support Rollers 4.3.3 Blocking Hook Function Method 4.3.4 Error Processing 4.3.5 By Mediation DLL Calling Windows Sockets DLL 4.3.6 Windows Sockets Implementation of Internal Pair For Messages 4.3.7 Private API Interface Chapter 5 Sets of Interface Library Functions Reference 5.1 Windows Socket 1.1 Library Functions Reference 5.1.1 Accept () 5.1.2 Bind () 5.1 .3 closesocket () 5.1.5 getpeername () 5.1.6 getSockName () 5.1.7 getsockopt () 5.1.8 htonl () 5.1.9 htons () 5.1.10 inet_addr () 5.1.11 inet_NTOA () 5.1.12 ioctlsocket () 5.1.13 listen () 5.1.14 ntohl () 5.1.15 ntohl () 5.1.16 RECV () 5.117 recvfrom () 5.1.18 select () 5.1.19 Send 5.1.20 sentto () 5.1.21 setsockopt () 5.1.22 shutdown () 5.1.23 socket () 5.2 Database function 5.2.1 gethostbyaddr () 5.2.2 gethostbyname () 5.2.3 gethostname () 5.2.4 getProtobyname () 5.2.5 GetProtobynumber ) 5.2.6 getservbyname () 5.2.7 getservbyport () 5.3 WINDOWS spread function 5.3.1 WSAAsyncGetHostByAddr () 5.3.2 WSAAsyncGetHostByName () 5.3.3 WSAAsyncGetProtoByName () 5.3.4 WSAAsyncGetProtoByNumber () 5.3.5 WSAAsyncGetServByName () 5.3.6 WSAAsyncGetServByPort () 5.3.7 WSAAsyncSelect () 5.3.8 WSACancelAsyncRequest () 5.3.9 WSACancelBlockingCall () 5.3.10 WSACleanup () 5.3.11 WSAGetLastError () 5.3.12 WSAIsBlocking () 5.3.13 WSASetBlockingHook () 5.3.14 WSASetLastError ( 5.3.15 WSAStartup () 5.3.16 WSAUNHOKBLOCKINGHOK () Chapter 6 Extended Features of Windows Socket 2 6.1 Simultaneous Use Multiple Transfer Protocol 6.2 and Rear Compatibility 6.2.1 Source Codes 6.2. 2 Binary Compatibility 6.3 Registering Transfer Protocol in Windows Sockets 6.3.1 Using Multiple Protocols 6.3.2 SELECT () Function () Function () Function () Significance 6.4 Conversion 6.4 Regional Resolution 6.5 Overlap I / O and Event Objects 6.5.1 Event Object 6.5.2 Receive Operation Complete Indication 6.5.2.1 Blocking and waiting for the instructions.
6.5. Demolition of advanced function 6.11 extended byte order conversion routine 6.12 Dispersion / aggregation mode I / O 6.13 protocol unrelated multi-point communication 6.14 new set interface option list 6.15 new integration interface ioctl operation code 6.16 new function list seventh Chapter WINDOWS SOCKETS 2 extended library function brief reference 7.1 WSAACCEPT () 7.2 WSACLOSEEVENT () 7.3 WSACONNECT () 7.4 WSACREATEEVENT () 7.5 WSADUPLICATESOCKET () 7.6 WSAENUMNETWORKEVENTS () 7.7 WSAENUMPROTOCOLS () 7.8 WSAEVENTSELECT () 7.9 WSAGETOVERLAPPEDRESULT () 7.10 WSAGETQOSBYNAME () 7.11 WSAHTONL () 7.12 WSAHTONS () 7.13 WSAIOCTL () 7.14 WSAJOINLEAF () 7.15 WSANTOHL () 7.16 WSANTOHS () 7.17 WSARECV () 7.18 WSARECVDISCONNECT () 7.19 WSARECVFROM () 7.20 WSARESETEVENT () 7.21 WSASEND () 7.22 WSASENDDISCONNECT () 7.23 WSASENDTO ( 7.24 wsasete () 7.25 wsasocket () 7.26 WSAITFORMULTIPEEVENTS () Appendix A Error Code Appendix B Windows Sockets header file Appendix B.1 Windows Sockets 1.1 header file Appendix B.3 Winsock.def file Appendix B.3 Winsock.def file Appendix B C References Chapter 1 Introduction 1.1 What is the Windows Sockets specification? Windows Sockets specification defines a set of MicoSoft W in the popular Socket interface popular in BSD UNIX in UC Berkeley University. Network programming interface under IndOws. It not only contains the library function of the Berkeley socket style that people are familiar with; also includes a set of extended library functions for Windows so that programmers can make programmers to program with Windows messaging mechanisms. The Windows Sockets specification is intended to provide a simple API to the application developer and let all network software vendors comply with. In addition, on the basis of a specific version Windows, Windows Sockets also defines a binary interface (ABI) to ensure that the application of the Windows Sockets API can work in accordance with the Windows Sockets protocol of Windows Sockets protocols. . Therefore, this specification defines a set of library functions that the application developer can use and the network software vendor can implement. Comply with this web software of this Windows Sockets, we call Windows Sockets compatible, and Windows Sockets-compatible providers, we call Windows Sockets providers. A network software vendor must implement the Windows Sockets specification percent to achieve Windows Sockets compatibility. Any application that can be compatible with Windows Sockets is considered to have a Windows Sockets interface. We call this application for the Windows Sockets application.
The Windows Sockets specification defines and records how to use the API and the Internet protocol (IPS, usually we refer to TCP / IP), especially pointed out that all Windows Sockets implementation supports juncture interfaces and data sets. The program calls the API of Windows Sockets to implement communication between each other. Windows Sockets uses the next network communication protocol function and operating system call to implement actual communication work. The relationship between them is shown in Figure 1-1. Although we don't object to use this set of APIs to achieve another communication protocol stack (and we expect to discuss this problem in future regulations), this usage has exceeded our specification, We will not be discussed here. 1.2 Bekeley socket The Windows Sockets specification is built on the Bekeley socket model. This model is now the standard of TCP / IP network. It provides a very familiar environment that is used to UNIX socket programming, and simplifies the work of port existing socket-based application source code. The Windows Sockets API is also consistent with the requirements of 4.3BSD. 1.3 Microsoft Windows and extended Windows Sockets API for Windows Sockets APIs can be used on all 3.0 or more version of Windows and all Windows ScokeTs implementations, but not only provide 16-bit operating environments for WindWos Sockets applications, but also A 32-bit operating environment is also provided. Windows Sockets also supports multi-threaded Windows processes. A process contains one or more simultaneous threads. In Windows 3.1 Non-multi-threaded versions, a task corresponds to a process with only a single thread. The threads we mentioned in this book refer to true threads in multi-threaded Windows environments. This term in non-multi-threaded environments (eg Windows 3.0) refers to the Windows Sockets process. The Windows Sockets specification provides application developers with the development of Windows applications for application developers. It helps programmers write more stable and more efficient programs, which also helps to make multiple applications to make multiple applications better in multitasking in a multitasking. Except for WSAStartup () and WSACleanup (), other Windows extended functions are not mandatory. 1.4 The status of this specification Windows Sockets is an independent specification. Its generation and existence is to benefit applications developers, network software vendors and major computer users. Each of this standardized version (non-draft) actually represents a complete set of APIs used for web software vendors and application developers. The discussion and improvement of this set of specifications are still underway. This discussion is mainly conducted by an email @microdyne.com through an Email Forum on the Internet. There is also a regular meeting. The specific content of the meeting will be published on the email forum. 1.5 Modified modifications 1.5.1 Windows Sockets 1.0 Windows Sockets 1.0 represents the crystallization of the network software vendor and the user association. The release of Windows Sockets 1.0 specification is to allow network software vendors and application developers to begin building their implementation and applications that comply with Windows Sockets standards. 1.5.2 Windows Sockets 1.1 Windows Sockets 1.1 inherits the criteria and structure of Windows Sockets 1.0, and only changes in some absolutely necessary places. These changes are based on many companies that have experienced experience and lessons in creating Windows Sockets 1.0 implementation. Windows Scokets 1.1 contains some clearer instructions and small changes to Windows Sockets 1.0.
Furthermore 1.1 also contains a major change: * Join gethostname () regular calls to get the host name and address more simply. * Define the number of orders in the DLL of 1000 is Windows Sockets reserved, and no limit on the order of greater than 1000. This allows Windows Sockets vendors to add their own interfaces in the DLL without having to worry about the selected number of sequences and conflicts in the future version of Windows Scokets. * Added associations between WSAStartup () functions and Wasclearup () functions, requiring two functions to correspond to each other. This makes the application developer and third-party DLL do not need to consider calls to this API when using the Windows Sockets implementation. * Change the return type of the function INTR_ADDR (), from the structure in_addr to an unsigned long integer. This change is to adapt to the different processing methods of the Microsoft C compiler and the Borland C compiler on the return type of four-byte structure. * Change the wsaasyncselect () function semantic from "edge trigger" to "level trigger". This approach greatly simplifies an application call to this function. * Change the semantics of Fionbio in the ioctlsocket () function. If there is an unfinished WSAAsyncSelect () call, the function will fail back. * In order to comply with RFC 1122, TCP_Nodelay is added to the socket option. All Windows Sockets 1.1 changes to Windows Sockets 1.0. Chapter II programming in this chapter using Windows Sockets 1.1, we will show how to use Windows Sockets 1.1 programming and discuss some of the details that use Windows Sockets 1.1 programming. The discussion of this chapter is based on Windows Sockets 1.1 specification, in some respects may be inconsistent with the discussion of Windows Sockets 2 in some respects, please pay attention to this difference. 2.1 Windows Sockets Protocol Stack Installation Check Any application with the Windows Sockets Import Library Joints Simply call the WSAStartup () function to detect that there is one or more Windows Sockets implementations in the system. For a slightly clever application, it checks the PATH environment variable to find an instance with a Windows Sockets implementation (Windows Sockets.dll). For each instance, the application can issue a loadLibrary () call and use the WSAStartup () function to get the specific data of this implementation. This version of the Windows Sockets specification does not have to discuss how many concurrent Windows Sockets implementation work together. However, there is no provision in this specification that can be interpreted to limit multiple Windows Sockets DLLs and are called simultaneously by one or more applications. 2.2 Set 2.2.1 Basic Concept Communication The cornerstone is a socket, a socket is one end of communication. On this end you can find a name corresponding to it. A socket that is being used has its type and related processes. The socket exists in the communication domain. The communication domain is an abstract concept introduced to handle the general thread through the socket communication. The socket is usually exchanged with sockets in the same domain (data exchange may also pass the boundaries of the domain, but at this time you must perform some explanation). The Windows Sockets specification supports a single communication domain, which is an Internet domain. Various processes use this domain to communicate with an Internet protocol between each other (Windows Sockets 1.1 or more support for other domains, such as Windows Sockets 2). The socket can be classified according to the communication nature; this property is visible to the user. Applications generally communicate only in the sockets of the same class.
However, as long as the underlying communication protocol is allowed, different types of sockets can also be communicated. The user can use two sockets, namely junction interfaces, and data sets. The junction interface provides two-way, orderly, no duplicate data stream services. The data setup interface supports the two-way data stream, but it is not guaranteed to be reliable, orderly, and no repetition. That is, a process from receiving information from a data settlement interface is possible to find that the information is repeated, or P [; '// - 0 is also issued. An important feature of the data settlement interface is that it retains the record boundary. For this feature, the data settlement interface uses a model that is very similar to now many package switched networks (such as Ethernet). 2.2.2 Client / Server Model One most common examples when establishing a distributed application is a client / server model. In this program, the client application requests services to the server program. This approach implies asymmetry when establishing inter-client communication. The client / server model requires a set of conventions convention consensus consensus to clients and servers to ensure that the service can be supplied (or accepted). This set of conventions contain a set of protocols. It must be implemented in both the communication. Depending on the actual situation, the agreement may be symmetrical or asymmetric. In the symmetrical protocol, each party may play a master from the role; in the asymmetric protocol, one party is not changed to be a host, and the other is the slave. An example of a symmetrical protocol is a Telnet for terminal simulation in the Internet. And an example of an asymmetric agreement is an FTP in the Internet. Regardless of the specific protocol is symmetrical or asymmetric, there must be "customer processes" and "service process" when the service is provided. A service program is usually a well-known address to listen to the service request, that is, the service process has been in a sleep state until a customer puts a connection request for the address of this service. At this moment, the service program is "awakened" and provides customers with services - the appropriate response to the client's request. This request / corresponding process can be represented by Figure 2-1. Although connection-based services are criteria for designing client / server applications, some services are also available through data sets. 2.2.3 External Data Note: The following discussions on external data (also known as TCP emergency data) are based on the BSD model. User and implementors must pay attention to the current interpretation of the RFC 793, which is based on this, is introduced by this concept. Moreover, BSD does not meet the requirements of the host of RFC 1122, and the application developer is best not to use the external data, unless a part of the services that do not use the communication with one of the services. It is necessary to operate. Windows Sockets providers must also provide their products for semantic text (using BSD methods or RFC 1122). It is specified that a special out-of-band data semantic set has exceeded the discussion scope of the Windows Sockets specification. The abstraction of the junction interface includes the concept of out-of-band data, with external data is a logically independent transmission channel between each pair of jacket interfaces. The external data is transmitted to the user independently of ordinary data. This abstract data device must support at least one out-of-band data message is reliably transmitted every hour. This message may contain at least one byte; and only one out-of-band data information is sent at any time. For communication protocols that only support within the band (eg, emergency data is sent to normal data), the system typically stores emergency data from normal data. This allows the user to make a selection between emergency data and inseparable reception of emergency data (in the order of sequential reception). In this case, the user can "peek" emergency data. A application may also like to deal with emergency data in the line, that is, as part of the normal data stream.
This can be implemented by setting SO_OOBINLINE in the setup interface option (see Section 5.1.21, setsockopt ()). In this case, the application may want to determine which of the unread data is "emergency" ("emergency" term usually applied to the line over-line data). In order to achieve this, in the implementation of Windows Sockets, it is necessary to keep a logical mark on the data stream to indicate which point of the external data begins to send, one application can use the Siocatmark IOCTLSocket () command (see Section 5.1.12) to determine Whether there is not read data before the marker. The application can use this mark to resynchronize the other party. The WSaAsyncSelect () function can be used to process notifications from external data. 2.2.4 Broadcasting Data Support Sets The interface can be used to send broadcast packets to many networks supported. To implement this function, the network itself must support broadcast functions because system software does not provide any simulation of broadcast functionality. Broadcasting information will cause a load to the network because they require each host on the network to serve them, so the ability to send broadcast packets is limited to the sockets that are explicitly marked allowed broadcasts. Broadcasting is usually used for two reasons: 1. An application wants to find a resource in the local network, and the application has no prior knowledge of the address of the resource. 2. Some important functions, such as routing requirements to send their information to all neighters that can be found. The destination address of the broadcast information depends on this information broadcast on the network. A shorthand address is supported in the Internet domain for broadcast -inaddr_broadcast. Since the use of broadcasts must be bundled with a data settlement interface, all received broadcast messages have the sender's address and port. Some types of networks support a variety of broadcasting concepts. For example, the IEEE 802.5 token ring structure supports link layer broadcast instructions, which are used to control whether broadcast data is sent over bridge. The Windows Sockets specification does not provide any mechanism to determine that an application is based on what network, and there is no way to control the semantics of the broadcast. 2.3 Byte Sequence The byte order of the INTEL processor is consistent with the byte order of the DEC VAX processor. Therefore, it is different from the 68000 processor and the order of the Internet, so the user should be particularly careful to ensure the correct order. Any IP address and port number from the Windows Sockets function to the IP address and port number and the IP address and port number of the Windows Sockets function are organized according to the network sequence, which also includes the IP address domain and port in the data type of the SockAddr_in structure. Domain (but excluding SIN_FAMILY). Considering an application usually uses ports corresponding to the Time service to connect to the server, the server provides a mechanism to notify the user to use another port. Therefore, the port number returned by the GetServByname () function is already in the network order, and can be used directly to form an address without the need for conversion. However, if the user enters a number, and specifies the use of this port number, the application must convert it from the host sequence into a network order before using it to create an address (using the htons () function). Accordingly, if the application wants to display port numbers contained in an address (eg, from the getPeerName () function), this port number must be converted from the network to the host sequence before being displayed (using NTOHS. )function). Since the byte order of the Intel processor and Internet is different, the above conversion is unavoidable, the application's writer should use the standard conversion function as part of the Windows Sockets API, instead of using its own conversion function code. Because the future Windows Sockets implementation is possible to run on the host byte order and network byte sequence. Therefore, only applications using standard conversion functions are portable.
2.4 Set Properties Options Windows Sockets Specification Supported socket property options are listed in the description of the setSockopt () function and getSockopt () function. Any Windows Sockets implementation must be able to identify all of these attribute options and return reasonable values for each property option. The default value of each attribute option is listed in the following table: Option type meaning Default value precautions SO_ACCEPTCON BOOL socket is listening. The False SO_BROADCAST BOOL socket is set to send broadcast data to False. SO_DEBUG BOOL allows Debug. False (*) S0_DONTLINGER BOOL If you are true, the SO_LINGER TRUE option is disabled. SO_DONTROUTE BOOL routing is prohibited. False (*) SO_ERROR INT is obtained and the error status is cleared. 0 SO_KEEPALIVE BOOL activity is being sent. False SO_LINGER STRUCT Returns current Linger information. L_onoff linger is 0 FAR * SO_OOBINLINE BOOL out-of-band data is being received in normal data flow False. SO_RCVBUF INT Receives buffer sizes. Determined whether the address FALSE that is bundled with the implementation (*) SO_REUSEADDR BOOL can be used by others. SO_SNDBUF INT Sends buffer size. Decided on the implementation (*) SO_TYPE INT socket type (such as the socket_stream). When creating, the same TCP_NodeLay Bool is disabled from using Nagle to determine the implementation of the merger. (*) Windows Sockets implementation is possible to ignore these properties when the user calls the setsockopt () function, and returns a value that has not changed when the user calls the getSockOpt () function. Or it may accept a value when setsockopt () and return the corresponding value when getSockOpt (), but in fact, it does not use it anywhere. 2.5 Database File getxByy () and WSAAYNCGETXBYY () This class is used to get some special network information. GetxByy () routines were initially (in the first edition of Berkely Unix) was designed as a mechanism for querying information in a text database. Although the Windows Sockets implementation may be available in different ways, the Windows Sockets application requires the information obtained by getXBYY () or WSAAYNCGETXBYY (). The information is consistent. 2.6 Different from the Berkeley sockets have some very limited places, the Windows Sockets API must be liberated from the strict adherence to the traditional Berkeley traditional style. Usually do this because the difficulty implemented in the Windows environment. 2.6.1 Setting Data Types and Error Numerical Windows Sockets Specification Define a new data type Socket, which is essential for future upgrades for the future Windows Sockets specification. For example, in Windows NT, the socket is used as a file handle. This type of definition also guarantees the portability of the application to the WIN / 32 environment.
Because this type will automatically upgrade from 16-bit to 32 bits. All handles in UNIX include a socket handle, which are non-negative short integers, and some applications treat this hypothesis as truth. The Windows Sockets handle does not limit this restriction, except for invalid_socket is not an effective socket, the socket can take any value between 0 to invalid_socket-1. Because the socket type is unsigned, the source code for the application that has existing in the UNIX environment may cause a warning that the Signed / Unsigned data type does not match. This also means that when the socket () routine and the accept () routine return, check if there is an error occurs, the method of comparing the return value and -1 should not be used, or if the return value is negative (both The method is very common in BSD, very legal ways). Instead, an application should use constant invalid_socket, which is defined in Winsock.h. For example: Typical BSD style: s = socket (...); if (s == -1) / * of S <0 * / {...} More excellent style: s = socket (...) ; If (s == invalid_socket) {...} {************************* READ THIS ********* **********}
2.6.2 SELECT () Function and FD_ * Macro Since a socket no longer represents a small non-negative integer in the UNIX style, the SELECT () function has some changes in the Windows Sockets API: each set of interfaces are still Use the fd_set type to represent, but it is not a bit mask. The socket of the entire group is implemented with an array of sockets. To avoid potential dangers, the application should insist on setting up, initialize, clear, and check FD_SET structures with FD_XXX macro. 2.6.3 Error Code - erno, h_errno, wsagetlasterror () Windows sockets implementation The error code set is not available through Errno variable. In addition, the error code cannot be obtained from the H_ERRNO variable for the function of getXByy (). The error code can be called using the wsagetlasterror () call. This function discusses in 5.3.11. This function is a pilot function for the Win / 32 function getLastError () implementation in the Windows Sockets implementation (eventually an alias). This is to provide a reliable guarantee for each thread in a multi-thread process. In order to maintain compatibility with BSD, the application can add the following line: #define errno wsagetlasterror () This ensures that the network program code written in the full-run errno variable can be used correctly in a single-threaded environment. Of course, there are many obvious shortcomings: if an original program contains a code to check the erroh variable on the socket and the non-socket function, this mechanism will not work. In addition, an application is impossible to assign a new value for Errno (in Windows Sockets, the wsasetlasterror () function can do this). For example: typical BSD style: r = recv (...); if (r == -1 / *, please see below * / & errno == ewouldblock) {...} More excellent style: r = recv (...); if (r == -1 / *, but please see below * / && wsagetlasterror () == ewouldblock) {...} Although the error constant is consistent with 4.3BSD in order to compatibility; Applications should be defined using the "WSA" series error code as much as possible. For example, a more accurate above program is: r = rv (...); if (r == -1 / * But see below * / && wsagetlasterror () == wsaewoldblock) {... } 2.6.4 Pointer All applications The pointers used by Windows Sockets must be a FAR pointer. In order to make it easy for application developers, the Windows Sockets specification defines data types LPHOSTENT. 2.6.5 Renameful functions There are two reasons in the Berkeley socket that must be renamed to avoid conflicts with other APIs: 2.6.5.1 Close () and CloseSocket () In the Berkeley socket, the form of interface appears in the form of the interface The standard file description word is the same, so the close () function can be used to close the socket with the closing regular file.
Although in the Windows Sockets API, there is no provision to hinder the Windows Sockets implementation file handle to identify the socket, but there is no rules that require this. The socket description word does not think that the normal file handle is corresponding, and does not think of file operations, such as read (), write () and close () do not guarantee correctly after applying to the socket. The socket must use the closSocket () routine to shut down, using a close () routine to close the socket is incorrect, and the effect is not known to the Windows Sockets specification. 2.6.5.2 IOCTL () and iOCTLSocket () Many C language runtime systems use IOCTL () routines for purposes of Windows Sockets, so Windows Sockets defines the IOCTLSocket () routine. It is used to implement features implemented with ioctl () and fcntl () in BSD. 2.6.6 Blocking routines and EinProgress Macro Although Windows Sockets supports blocking operations on sockets, this application is strongly opposed. If programmers are forced to use blocking mode (such as an existing program that is ready to transplant), Then he should clearly know the semantics of blocking operations in Windows Sockets. See Details See 4.12.6.7 Number of maximum interfaces supported by Windows sockets A maximum number of sockets supported by a specific Windows Sockets provider is determined by implementation. Any application should not be assumed to be available for a certain number of sockets. This will be reaffirmed in 4.3.15 WSAStartup (). And an application can truly use the number of sockets and the number supported by a particular implementation is completely independent. The maximum number of socket interfaces that can be used by a Windows Sockets application is determined by the constant fd_setsize when compiling. This constant is used in the Select () function (see 4.1.18) to form an FD_SET structure. The default value in Winsock.h is 64. If an application wants to use more than 64 sets of interfaces, the programmer must define the exact fd_set value before each source file contains Winsock.h. One way to complete this work is to join this definition on the compiler option in the project file. For example, add -D fd_setsize = 128 as a command line parameter for the compile command when using Microsoft C. To emphasize that the value of fd_set definitions has no effect on the number of sockets supported by Windows Sockets. 2.6.8 Header In order to facilitate the transplant of existing source code based on Berkeley socket, Windows Sockets supports many Berkeley header files. These Berkeley headers are included in Winsock.h. So a Windows Sockets application requires a simple enough to include Winsock.h (this is also a method recommended). 2.6.9 Return Value Constant Socket_ERROR is used to check the API call failure when the API call fails. Although the use of this constant is not mandatory, this is recommended.
The following example shows how to use a Socket_ERROR constant typical BSD style: r = recv (...); if (r == -1 / * or r <0 * / && errno == ewouldblock) {...} Excellent style: r = recv (...); if (r == socket_error && wsagetlasterror == wsaewouldblock) {...} 2.6.10 Original set The Windows Sockets specification does not specify that the Windows Sockets DLL must support the original socket interface - The socket opened with SOCK_RAW. However, the Windows Sockets specification encourages the Windows Sockets DLL to provide raw socket support. A Windows Sockets compatible application should try to use the Socket () call (see Section 5.1.23) when you want to use the original set of interfaces (see Section 5.1.23) to open the socket. If you fail, the application should use other types of sockets or report errors to users. 2.7 The Windows Sockets Windows Sockets interface in the multi-threaded Windows version is designed to be able to use both single-threaded Windows versions (such as Windows 3.1) and can be used in a multi-threaded Windows version (such as Windows NT), in multi-threaded environment. In the socket interface, the interface interface is basically constant. However, the authors of multi-threaded applications must know that the use of synchronous interfaces between threads is the responsibility of the application, not the responsibility for Windows Sockets. This is managed in other forms of I / O, such as file I / O is the same. No synchronization of socket calls will result in unpredictable results. For example, if there are two threads simultaneously call the same set of interfaces to perform send (), then the order of the data sent cannot be guaranteed. Close a unfinished blocking socket in a thread will cause another thread to use the blocked inclusions of the same set of interfaces to return an error (WSAEINTER), as if the action is canceled. This also applies to a Select () call is not completed, the application turns off one of the selected sockets. In a multi-threaded Windows version, there is no default blocking hook function. This is because if a single application is waiting for a certain operation and does not call PeekMessage () or getMessage () to generate a function of a non-populated window. Therefore, the machine will not be blocked in this case. However, in order to rearward compatibility, in multi-threaded Windows versions, the WsaseTBlockingHook () function is also implemented. Any application that uses the default blocking hook can install their own blocking hook functions to override the default blocking hook function. Chapter III Windows Sockets 1.1 Application Example In this chapter, the actual work of the author is background, which gives a specific example of using Windows Sockets 1.1 programming. And the example is analyzed in this example. This example debugged in Windows 3.1, Windows Sockets 1.1, and BSD OS for PC 2.0 (BSD UNIX Microcomputer Edition) environment.
3.1 Set of interface network programming principle sockets There are three types: streaming socket, data setsters interface and original socket. Flow socket defines a reliable connection-oriented service, achieving no errorless sequential data Transfer. Data Supplier Interface Defines a connectionless service. Data is transmitted by mutually independent packets, and does not guarantee reliability, no errors. Original socket allows the low-level protocol, such as IP or ICMP Access, mainly used for new network protocol implementations. Unconnected servers are generally transaction-oriented, a response to complement the interaction between client programs and service programs. If you use a connectionless socket programming, the process of the program can be represented by Figure 3-1. Request for connection server processing is often more complicated, not a request response to a request, and is often a concurrent server. Using a connection-oriented socket programming can be represented by Figure 3-1: the timing.
The socket work process is as follows: The server starts first, build a set of interfaces by calling socket (), then calls bind () links the interface and the local network address, then call listen () to make the socket to listen Prepare and specify its request queue length, then call accept () to receive the connection. If the customer can invoke connect () and server establish a connection after establishing a set of interfaces. Once the connection is established, the client and server can be By calling read () and write () to send and receive data. Finally, after the data transfer ends, both parties call close () closing socket. 3. Windows Sockets programming principle Due to Windows-based, Winsock and BSD socket Compared to some new expansion: 1. Asynchronous selection mechanism asynchronous selection function WSaasyncselect () allows applications to nominate one or more network events such as FD_READ, FD_WRITE, FD_CONNECT, FD_ACCEPT, and other network events. When the nominated network event occurs, the Windows application window function will receive a message. This allows the event driver. 2. Asynchronous request function asynchronous request function allows the application to obtain the requested information in an asynchronous manner, such as WSaasyncGetxbyy () Class function. These functions are the expansion of the BSD standard function. Functions WSAcanceLasyncRequest () allows users to abort an asynchronous request being executed. 3. Blocking processing method Winsock provides "hook functions" responsible for processing Windows messages, making Windows messages The loop can continue .Winsock provides two functions (WSASetBlockingHook () and WSAunhookBlockingHook ()) let the application set or cancel your own "hook function". Function wsaisblocking () can detect whether it is blocked, the function wsacancelblockingCall () can cancel a blocking Call. 4. Error handling Winsock provides two WSageTlasterror () and WSasetLastError () to get the nearest error number. 5. Start and terminate the use of Windows Sockets is implemented in the form of dynamic connection winsock.dll, so you must To initialize the WSAStartup () function first, negotiate the version of Winsock, and assign the necessary resources. After the application shuts down the socket, you should call wsacleanup () termination to Windo. WS Sockets DLL uses, and releases resources to prepare for the next use. In these functions, the key to implementing Windows network real-time communication is the use of asynchronous selection functions WSAAsyncSelect (). See page 5.3.7.3.3 Windows The Sockets and UNIX Set Interface Programming Example The following is a simple connection-based point-to-point real-time communication program. It consists of two parts, the server runs directly under the host Unix, the client runs under Windows. 3.3.1 Server Introduction Because Server is Under UNIX, it is the standard function of the BSD, and the program is also simple, only one program is briefly explained. First, build your own socket. In the interconnected network, the global identifies one The process requires a three-way group (protocol, local host address, local port number) called "semi-correlated", and a complete process communication instance requires a five-way group called "related" (protocol , Local host address, local port number, remote host address, remote port number) to describe. S = Socket (AF_INET, SOCK_STREAM, 0) This function establishes a set of interfaces, address formats under the specified address format, data type, and protocol. For AF_INET (uniquely supported format), data type SOCK_STREAM represents the establishment of stream socket, the parameter is 0, that is, the protocol is default. Bind (s, (Struct SockAddr *) &
Server, SIZEOF (Server) This function will establish a semi-related semi-related server locally, where Server is a SockAddr_in structure, and its members describe the local port number and the local host address. After bind () identifies the server process online. Then, Establish a connection. First call the listen () function representation Start listening. Then the Accept () call waits for the reception connection. Listen (s, 1) indicates that the connection request queue length is 1, that is, only one request, if there is a number of requests The error is an error, gives an error code WSAECONNREFUSED. NS = Accept (S, STRUCKADDR *) & Client, & Namelen) Accept () Block (Default) Waiting for Request Queue, once there is a connection request, the function Establish a new socket with the same properties. Client is also a SockAddr_in structure, and the semi-related information that fills in the socket of the request connection when the connection is established. Next, you can receive and send data. RECV (NS, BUF, 1024, 0) SEND (NS, BUF, PKTLEN, 0) The above two functions are responsible for receiving and transmitting data, respectively, Recv receives data from NS (set up connection) to BUF, Send will data in BUF Send it to NS. As for the fourth parameter, indicate the function call mode, you can select MSG_DONTROUTE and MSG_OOB, 0 to represent the default. Finally, close the socket. Close (ns); close (s); 3.3.2 Client introduction client It is running on Windows, using some of the Windows sockets extension functions, slightly complex. Includes .rc and .c two files, where the main window function clientProc () is the main part of the program, which is simply explained below. First, after winning the window in WinMain (), you will send a custom WM_USER message to the main window function, do the relevant preparation. In the main window function, receive the WSASTARTUP () function, first call the wsastartup () function. Initialize Windows Sockets DLL and check the version number. As follows: status = wsastartup (VersionReqd, lpmywsadata); where VersionReqd describes the Winsock version (here 1.1), LPMYWSADATA points to a WSADATA structure, which describes the implementation of Windows Sockets Details. After WSAStartup (), the process passes the host name (running the time To make a line parameter, get the host address, as follows: hostaddr = gethostByname (server_address); Hostaddr points to the HOSTENT structure, see 5.2.1. The process is then constantly messaging, waiting for the user to select "Start" through the menu. At this time, By calling the client () to start the socket. In the client (), first, the socket () is called to establish a sleeve. As follows: IF ((((s = socket, sock_stream, 0) == invalid_socket) {Alertuser (hwnd, "socket failed"); return (false);} Tight, call the wsaasyncselect () function Nominated FD_CONNECT network event, as follows: if (! setselect (hwnd, fd_connect) Return (false); setSelect () mainly Call wsaasyncselect (), let Windows Sockets DLL send a UM_Sock custom message when detecting connection is created, allowing the message loop to continue. As follows: BOOL setSelect (hwnd hwnd, long levent) {if (WSaasyncselect (s, HWND, UM_SOCK, LEVENT) == Socket_ERROR) {Alertuser (hwnd, "wsaasyncselect failure."); return (false);} return (TRUE);
} To establish a connection, you must call the connection immediately. Because of the first calling wsaasyncselect (), Connect () is a non-blocking call. Whether the process issues a connection request, Winsock DLL automatically sends a message after the connection is established. Give the main window function to run the program. Connect (S, S. (S, Struct SockAddr Far *) & DST_ADDR, SIZEOF (DST_ADDR)); After receiving the UM_SOCK message, it is determined which network event is caused by the first time. It is inevitably caused by the connection event, so that the corresponding block is performed, and setSelect () is invoked to nominate the FD_WRITE event. I hope to receive a message when the socket can be sent. When you receive an FD_WRITE message, first adjust Send () Send data, then calls setSelect () to nominate the FD_READ event, I hope that the receiving data is received in the socket. When receiving the fd_read message, first adjust the RECV () to receive the data and nominate the FD_WRITE event, so the loop Go down. Until the event fd_close connected closes, WSAAsYNCselect (S, HWND, 0, 0) is called to stop asynchronous selection. When the window function is connected to the WM_DESTROY message (ie before the window is closed), first call the closesocket () first. The role is closed with Close ()) in UNIX to close the socket, then call WSACLANUP () Terminate Windows Sockets DLL, and release the resource. 3.3.3 Source Program List Program 1: Client.rcClientMenu MenuBegin Popup "& Server" Begin MenuItem "& Start. .., 101 menuitem "& exit", 102 Endend program 2: client.c # define userport 10001 # define idm_start 101 # define idm_exit 102 # define um_sock wm_user 0x100 # include
if if return (FALSE) (hPrevInstance!) (InitApplication (hInstance)!); hInst = hInstance; hWnd = CreateWindow ( "ClientClass", "Windows ECHO Client", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, Hinstance, null; if (! hw) return (false); showwindow (hwnd, ncmdshow); UpdateWindow (hwnd); PostMessage (hwnd, wm_user, (wparam) 0, (lparam) 0); while (GetMessage (& MSG, NULL, NULL, NULL)) {TranslateMessage (& msg); DispatchMessage (& msg);} return (msg.wParam);} BOOL InitApplication (hINSTANCE hInstance) {WNDCLASS WndClass; char * szAppName = "ClientClass"; // fill in window class information WndClass.lpszClassName = (LPSTR) szAppName; WndClass.hInstance = hInstance; WndClass.lpfnWndProc = ClientProc; WndClass.hCursor = LoadCursor (NULL, IDC_ARROW); WndClass.hIcon = LoadIcon (hInstance, NULL); WndClass.lpszMenuName = " ClientMenu "; wndclass.hbrbackground = getStockObject (White_brush); WNDCLASS.STYLE = CS_HREDRAW | CS_VR EDRAW; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; // register the class if (RegisterClass (& WndClass)!) Return (FALSE); return (TRUE);} long FAR PASCAL ClientProc (HWND hWnd, unsigned message, UINT wParam, LONG lParam) {int length, i; WSADATA wsaData; int Status; switch (message) {case WM_USER: {WORD wMajorVersion, wMinorVersion; LPWSADATA lpmyWSAData; WORD VersionReqd; int ret; wMajorVersion = mAJOR_VERSION; wMinorVersion = mINOR_VERSION; VersionReqd = WSA_MAKEWORD (WMAJORVERSION, WMINORVERSION); lpmywsadata = (lpwsadata) Malloc (Sizeof (Wsadata)); status =
WSAStartup (VersionReqd, lpmyWSAData); if (Status = 0!) {AlertUser (hWnd, "WSAStartup () failed / n"); PostQuitMessage (0);} hostaddr = gethostbyname (server_address); if (hostaddr == NULL) { AlertUser (hWnd, "gethostbyname ERROR / n!"); WSACleanup (); PostQuitMessage (0);} _fmemcpy (& hostnm, hostaddr, sizeof (struct hostent));} break; case WM_COMMAND: switch (wParam) {case IDM_START: If (! client (hwnd)) {CloseSocket (s); Alertuser (hwnd, "start failed");} Break; Case IDM_EXIT: // wsacleanup (); PostquitMessage (0); Break;} Break; Case Um_sock: Switch (lParam) {CASE FD_CONNECT: IF (! setSelect (hwnd, fd_write)) CloseSocket (s); Break; Case FD_Read: if (! ReceivePacket (HWND)) {Alertuser (HWND, "Receive Packet Failed./N"); CloseSocket (S); Break;} if (! setselect (hwnd, fd_write) CloseSocket (s); Break; Case FD_WRITE: FOR (i = 0; i <1024; i ) Buffer [I] = (char) 'a' I% 26; Length = 1024; if (! sendpacket (hwnd, length)) {Alertuser (hwnd, "packet send! / n"); CloseSocket (s); Break;} if (! setselect (hwnd, fd_read)) CloseSocket (s); Break; Case FD_Close: IF (Wsaasyncselect (s, hwnd, 0, 0) == Socket_ERROR) ALERTUSER (HWnd, "Wsaasyncselect Failed./N" Break; default: IF (WsagetSelectError (LPARAM)! = 0) {Alertuser (HWnd, "Socket Report Failure."); ClosSocket (s); Break;} Break;} Break; Case WM_DESTROY: CloseSocket (s); WSACLEANUP ();
PostQuitMessage (0); break; default: return (DefWindowProc (hWnd, message, wParam, lParam));} return (NULL);} void AlertUser (HWND hWnd, char * message) {MessageBox (hWnd, (LPSTR) message, "Warning", MB_ICONEXCLAMATION); return;} BOOL Client (HWND hWnd) {memset (& dst_addr, '/ 0', sizeof (struct sockaddr_in)); _fmemcpy ((char FAR *) & dst_addr.sin_addr, (char FAR *) hostnm .h_addr, hostnm.h_length); dst_addr.sin_family = hostnm.h_addrtype; dst_addr.sin_port = htons (USERPORT); if ((s = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {AlertUser (hWnd, "Socket Failed "); return (false);} if (! SetSelect) Return (False); Connect (S, Struct SockAddr Far *) & Dst_addr, SizeOf (DST_ADDR)); Return (True);} BOOL ReceivePacket (HWND HWND) {HDC HDC; Int Length; Int I1, I2, I3; Char line1 [255], Line2 [255], LINE3 [255]; Count ; IF ((Length = Recv (S, LPBuffer) 1024, 0) == SOCKET_ERROR) RETURN (false); if (length == 0) Return (false); if (HDC = GETDC (HWND)) {I1 = WSPRINTF ((LPSTR) line1, "TCP Echo Client No.% D ", Count; I2 = WSPrintf ((LPSTR) line2," Receive% D Bytes ", Length); i3 = WSPrintf ((LPST) line3," Those Are:% C,% C,% C,% C,% C,% C ", Buffer [0], Buffer [1], Buffer [2], Buffer [100], Buffer [1000], BUFFER [1023]); Textout (HDC, 10, 2 Line1, I1); Textout (HDC, 10, 22, (LPSTR) line2, i2); Textout (HDC, 10, 42, (LPSTR) line3, i3); ReleaseDC (HWND, HDC);} return (True); Bool SetSelect (hwnd hwnd, long levent) {IF (WSaasyncselect (s, hwnd, um_sock, levent) == Socket_ERROR) {Alertuser (hwnd, "wsaasyncselect failure); return (false);} return (TRUE);
} Bool sendpacket (hwnd hwnd, int LEN) {INT Length; IF ((Length = Send (s, lpbuffer, len, 0)) == Socket_ERROR) RETURN (false); Else IF (Length! = LEN) {Alertuser HWnd, "Send Length Not Match!"); return (true);} Return (true);} program 3: server.c # incrude
WSHOUT In this section, we will further discuss Windows Sockets programming technology through a carefully selected example. For example, how to develop clients or server programs, how to apply TCP has a connection service (streaming socket) or UDP-free service (data settlement interface), how to block or unblocked socket operations, etc., these are I often encounter problems. The WSHOUT program to be introduced will be introduced, which can achieve any combination of the above application by flexibly set different options, so that the problem that the application of Windows Sockets programming can basically have a good research reference value. Since the program is clear, the structure is sophisticated, so we don't plan to analyze each statement in detail, but just briefly introduce the logical structure of the entire program and add the appropriate annotation in the source program. We believe that any readers with basic C language and Windows programming experience can easily read most of the content. After careful chewing and scrutinizing, you can get some inspiration to prepare a quality program. This program is probably adopted in the FTP company's PCTCP support environment, but as long as the reader has any implementation that meets the implementation of Windows Sockets 1.1 specification, the program can also perform the program smoothly. 3.4.1 Source Program Contents 1. WSHOUT.C WSHOUT Main Program 2. WSHOUT.H WSHOUT Header file 3. WSHOUT.RC WSHOUT Resource File 4. USHOUT.C UDP Client Program 5. Ulisten.c UDP Server Program 6. TSHOUT .C TCP client program 7. TLISTEN.C TCP server program 8. Errno.c Gets WSAE * Error Description String Program 9. The RESOLVE.C Client / Server Starter When compiling this program, the author uses BC3. 1. Simply do a PRJ engineering file, will include the above .C files and winsock.lib. Note that Winsock.h should be built in the include directory or current directory, Winsock.lib can be created with the Implib tool using Winsock.dll. If the reader uses other compilers, they can be adjusted according to their own, and will not be described here.
3.4.2 Program Logic Structure 3.4.3 Source Prices List and Note 3.4.3.1 WSHOUT.C List / * * File Name: WSHOUT.C * / / * MSC include Files: * / # include
msg, NULL, NULL, NULL)) {TranslateMessage (& msg); / * translation of the virtual key code * / DispatchMessage (& msg);} return (msg.wParam);} BOOL InitApp (HANDLE hInstance) {HANDLE hMemory; PWNDCLASS pWndClass; BOOL bSuccess; hMemory = LocalAlloc (LPTR, sizeof (WNDCLASS)); pWndClass = (pWNDCLASS) LocalLock (hMemory); pWndClass-> hCursor = LoadCursor (NULL, IDC_ARROW); pWndClass-> hIcon = LoadIcon (hInstance, (LPSTR) " SHOUT "); pWndClass-> lpszMenuName = (LPSTR)" MainMenu "; pWndClass-> lpszClassName = (LPSTR)" MainMenu "; pWndClass-> hbrBackground = GetStockObject (WHITE_BRUSH); pWndClass-> hInstance = hInstance; pWndClass-> style = NULL; pWndClass-> lpfnWndProc = ShoutWndProc; bSuccess = RegisterClass (pWndClass); LocalUnlock (hMemory); LocalFree (hMemory); return (bSuccess);} long FAR PASCAL ShoutWndProc (HWND hWnd, WORD message, WORD wParam, LONG lParam) { FarProc LPDialogBoxProc; switch (message) {copy wm_create: / * put up the dialog box * / lpdialogboxproc = makeproci nstance (DialogProc, hInst); DialogBox (hInst, (LPSTR) "MainDialog", hWnd, lpDialogBoxProc); FreeProcInstance (lpDialogBoxProc); PostMessage (hWnd, WM_DESTROY, 0, 0L); break; case WM_DESTROY: PostQuitMessage (0); break ; default: return (DefWindowProc (hWnd, message, wParam, lParam));} return NULL;} BOOL FAR PASCAL DialogProc (HWND hOurDlg, WORD message, WORD wParam, LONG lParam) {FARPROC lpProcAbout; FARPROC lpProcSettings; long lret; WORD Wmajorversion, WMINORVERSION; Char Hostnm [64];
/ * Include the host name of the work buffer * / switch (message) {case wm_initdialog: / * Select the default host * / setdlgitemtext (Hourdlg, IDD_HNAME, ""); senddlgitemmessage (HOURDLG, / * dialog handle * / IDd_hname, / * Send MSG * / EM_SETSEL, / * Select Character * / NULL, / * Additional Information * / Makelong (0, 0x7FFF)); / * All content * / setfocus (Getdlgitem (Hourdlg, IDD_HNAME)); / * initialization * / hMainDlg = hOurDlg; / * save their window handle * / SetDlgItemText (hOurDlg, IDD_COHOST, "Shout to:"); wMajorVersion = mAJOR_VERSION; wMinorVersion = mINOR_VERSION; VersionReqd = WSA_MAKEWORD (wMajorVersion, wMinorVersion); lpmyWSAData = ( LPWSADATA) _Calloc (1, sizeof (wsadata)); RET = WSAStartup (VersionReqd, lpmywsadata); if (Ret! = 0) {WSHOUT_ERR (HOURDLG, WsageTlasterror (), "WSAStartup ()");} Return (TRUE); case WM_CLOSE: PostMessage (hOurDlg, WM_COMMAND, IDM_EXIT, 0L); break; case WM_SYSCOMMAND: SendMessage (hOurWnd, message, wParam, lParam); break; case WM_COMMAND: switch (wParam) {case IDD_CONNECT: / * connect button is pressed * / Case IDM_Start: / * Select the Start menu item * / run_cancelled = false; / * Cannot go back * / if (running) {MessageBox (Hourwnd, "Shout is already Running!", "Shout", MB_ok | MB_APPLMODAL | MB_ICONEXCLAMATION); return FALSE;} ClearBoxes (hOurDlg); running = TRUE; if (iClientOrServer == iShout) {/ * make sure that the host name * / if (GetDlgItemText (hOurDlg, IDD_HNAME, hostnm, 80) <2) {MessageBeep ( 0); setdlgitemtext (HOURDLG, IDD_COMMENT, "NO HOSTNAME Specified"); Running = False; Break;} SD = ResolveandConnectHost (Char Far *) Hostnm, Hourdlg, iProto, iPortno;
IF (SD == SOCKET_ERROR) {/ * Unable to create a set of interface * / running = false; break;}} else {sd = getSocketandbind (Hourdlg, iProto, iportno); if (SD == Socket_ERROR) {Running = false; Break ;}} / * Set the I / o mode of the socket * / if (blocking_option) {LRET = 1L; / * Non-blocking mode * / ioctlsocket (SD, Fionbio, (U_LONG FAR *) & lret);} else {LRET = 0L; / * Block mode * / ioctlsocket (SD, Fionbio, (U_LONG FAR *) & lret);} f (iClientorServer == ISHOUT) {/ * shout * / / * generates data and writes set interface * / if ( iProto == ITCP) LRET = TWRITEDATA (SD, HOURDLG, LEN); ELSE / * UDP * / LRET = UWriteData (SD, HOURDLG, LEN);} else {/ * listen * / if (iProto == ITCP) LRET = TreadData (SD, HOURDLG, LEN); ELSE / * UDP * / LRET = UREADDATA (SD, Hourdlg, Len);} ClosSocket (SD); Running = False; Break; Case IDd_cancel: if (Running) {/ * Stop * / RET = WSAcancelBlockingCall (); run_cancelled = true; if (ret == Socket_ERROR) {/ * WSANOTINITIALISED or WSAENETDOWN or WSAEINVAL * / if (h_errno == WSAENETDOWN) {/ * Watch out for hAcceptSock * / / * close what is left of the connection * / closesocket (sd);!}}} Break; case IDM_EXIT : ret = WSACleanup (); if (ret == SOCKET_ERROR && h_errno == WSAEINPROGRESS) {MessageBox (hOurWnd, "Data transfer in progress./nStop transfer first.", "WndProc ()", MB_OK | MB_APPLMODAL | MB_ICONINFORMATION); Break; / * A socket is in a blocking state * /} _free ((char Near *) lpmywsadata); enddialog (hourdlg, true); / * Exit * / Break;
case IDM_ABOUT: lpProcAbout = MakeProcInstance (About, hInst); DialogBox (hInst, "AboutBox", hOurDlg, lpProcAbout); FreeProcInstance (lpProcAbout); break; case IDM_SETTINGS: lpProcSettings = MakeProcInstance (Settings, hInst); DialogBox (hInst, "SettingsDialog ", HOURDLG, LPPROCSETTINGS; FreeProcinstance (LPPROCSETTINGS); Break; default: Break;} / * switch (wparam) * / Break;} / * switch (message) * / return false;} / * This function processes the About dialog * / BOOL FAR PASCAL About (HWND hDlg, WORD message, WORD wParam, LONG lParam) {char tempBuf [15]; switch (message) {case WM_INITDIALOG: SetDlgItemText (hDlg, IDA_COPYRIGHT, (LPSTR) lpmyWSAData-> szDescription); wsprintf (Tempbuf, "% d.% 2d / n", major_version, minor_version; setdlgitemtext (HDLG, IDA_APP_VERSION, (LPSTR) TEMPBUF; WSPRINTF (Tempbuf, "% D.% 2D / N", lpmywsadata-> wversion% 256 , lpmywsadata-> wversion / 256); setdlgitemtext (HDLG, IDA_DLL_VERSION, (LPSTR) TEMPBUF; Return (false); case wm_command: if (wparam == idok || WPARAM == IDCANCEL) {enddialog (hdlg, true); return (true);} Break;} return (false);} / * This function is processed to process Settings dialog * / Bool Far Pascal settings (HWND HDLG, Word Message, Word WPARAM , LONG lParam) {int buffer_len = len; int port_no = iPortNo; switch (message) {case WM_INITDIALOG: / * Select a default send () buffer length * / SetDlgItemInt (hDlg, IDS_BUFFLEN, len, 0); / * Select a default port number * / SetDlgItemInt (hDlg, IDS_PORTNO, iPortNo, 0); if (iClientOrServer == iShout) / * program type * / CheckThisProgBoxOn (hDlg, IDS_CLIENT); else CheckThisProgBoxOn (hDlg, IDS_SERVER); if (iProto == iTCP ) / * Protocol type * / checkthisprotoboxon (HDLG, IDS_TCP);
else CheckThisProtoBoxOn (hDlg, IDS_UDP); if (! blocking_option) / * blocking mode * / CheckThisBoxOn (hDlg, IDS_BLOCK); else CheckThisBoxOn (hDlg, IDS_NOBLOCK); SendDlgItemMessage (hDlg, / * dialog handle * / IDS_PORTNO, / * where to Send msg * / em_setsel, / * select characters * / null, / * additional info * / makelong (0, 0x7fff)); / * entire contents * / senddlgitemmessage (hdlg, / * dialog handle * / ids_bufflen, / * where to Send msg * / em_setsel, / * select characters * / null, / * additional info * / makelong (0, 0x7FFF)); / * entire contents * / setfocus (getdlgitem (hdlg, ids_bufflen); Return (TRUE); Case WM_COMMAND: switch (wParam) {case IDS_CLIENT: / * USer has set to Shout * / CheckThisProgBoxOn (hDlg, IDS_CLIENT); tClientOrServer = iShout; SetDlgItemText (hMainDlg, IDD_COHOST, "Foreign host:"); SetDlgItemText (hMainDlg, IDD_HNAME, " "); Break; Case IDs_server: / * user HAS set to listen * / checkthisprogboxon (HDLG, IDS_SERVER); TCLIENTORSERV er = iListen; SetDlgItemText (hMainDlg, IDD_COHOST, "Listening to:"); SetDlgItemText (hMainDlg, IDD_HNAME, "[Hit 'Start']"); break; case IDS_TCP: / * USer has set to TCP * / CheckThisProtoBoxOn (hDlg , IDS_TCP); temporary_protocol = iTCP; break; case IDS_UDP: / * USer has set to UDP * / CheckThisProtoBoxOn (hDlg, IDS_UDP); temporary_protocol = iUDP; break; case IDS_BLOCK: / * User has set to blocking mode * / CheckThisBoxOn ( HDLG, IDS_BLOCK; Temporary_Option = 0L; Break; Case IDs_noblock: / * user Has Set to Nonblocking Mode * / CheckThisboxon (HDLG, IDS_NOBLOCK); Temporary_Option = 1L; Break;
CASE IDOK: / * User has completed the settings of the settings * / buffer_len = getdlgitemint (HDLG, IDS_BUFFLEN, NULL, 0); if (buffer_len == 0 || buffer_len> 8192) {MessageBox (HOURWND, "Buffer Length Must Be between 1 and 8K "," settings () ", MB_OK | MB_APPLMODAL | MB_ICONSTOP); Return (false);} port_no = getdlgitemint (HDLG, IDS_PortNo, NULL, 0); if (port_no == 0) {MessageBox (HDLG," Port number must be between 0 and 65,535 "," Settings () ", MB_OK | MB_APPLMODAL | MB_ICONSTOP); return (FALSE);} len = buffer_len; iPortNo = port_no; blocking_option = temporary_option; iProto = temporary_protocol; iClientOrServer = tClientOrServer; case IDCANCEL: / * Users do not want to change the settings * / enddialog (hdlg, true); return (true); default: break;} default: Break;} return (false);} void checkthisboxon (hwnd hdlg, int buttonid) {switch ({) {Switch ButtonID) {CASE IDS_BLOCK: CheckdlgButton (HDLG, IDS_BLOCK, 1); CheckdlgButton (HDLG, IDS_NOBLOCK, 0); BREAK; CA se IDS_NOBLOCK: CheckDlgButton (hDlg, IDS_BLOCK, 0); CheckDlgButton (hDlg, IDS_NOBLOCK, 1); break; default: break;} return;} void CheckThisProtoBoxOn (HWND hDlg, int ButtonID) {switch (ButtonID) {case IDS_TCP: CheckDlgButton (hDlg, IDS_TCP, 1); CheckDlgButton (hDlg, IDS_UDP, 0); break; case IDS_UDP: CheckDlgButton (hDlg, IDS_TCP, 0); CheckDlgButton (hDlg, IDS_UDP, 1); break; default: break;} return;} void CheckThisProgBoxOn (HWND hDlg, int buttonID) {switch (buttonID) {case IDS_CLIENT: / * Shout * / CheckDlgButton (hDlg, IDS_CLIENT, 1); CheckDlgButton (hDlg, IDS_SERVER, 0); break;
Case IDS_Server: / * listen * / checkdlgbutton (HDLG, IDS_CLIENT, 0); CheckdlGButton (HDLG, IDS_SERVER, 1); Break; default: Break;} return;} / * Here is how we handle "simulation block" - this function Check the message queue. If you find the message you need to process, a positive value is returned. * / IntShoutBlockingHook (void) {MSG msg; / * lets us pull messages via PeekMessage * / int ret = PeekMessage (& msg, NULL, 0, 0, PM_REMOVE); if (ret) {TranslateMessage (& msg); DispatchMessage (& msg) } Return ret;} char * _calloc (nelem, elsize) unsigned nlem, elsize; {handle hmem; pstr ptr; unsigned size = NELEM * ELSIZE; IF ((HMEM = localloc (lptr, size)) == null) Return (char *) 0; IF ((PTR = Locallock (HMEM)) == null) {localfree (hmem); return (char *) 0;} Return (char *) PTR;} void_free (void * CP) { void) LocalFree (LocalHandle ((WORD) cP));} void ClearBoxes (HWND hOurDlg) {wsprintf (prbuf, "/ n"); SetDlgItemText (hOurDlg, IDD_WRITE, (LPSTR) prbuf); SetDlgItemText (hOurDlg, IDD_SENT, ( LPSTR) prbuf); SetDlgItemText (hOurDlg, IDD_TIME, (LPSTR) prbuf); SetDlgItemText (hOurDlg, IDD_WRITES, (LPSTR) prbuf); SetDlgItemText (hOurDlg, IDD_BYTES, (LPSTR) prbuf); SetDlgItemText (hOurDlg, IDD_BITS, (LPSTR) PRBUF; Return;} / * * WSHOUT_ERR () function * Description: * * Get the corresponding corresponding Error Description Text, conjugated * before the error provided by the user, and is displayed in the dialog.
* / void WSHOUT_ERR (HWND HOURDLG, / * Dialog Window Handle * / INT WSA_ERR, / * WINSOCK Error Code * / Char Far * Err_PREFIX) / * Error Prefix Strings * / {Char Errbuf [PRBUF_LEN]; / * Error Description String Buffer * / / / * Get Error Description String * / WSASPERROR (Hinst, WSA_ERR, (LPSTR) Errbuf, PRBUF_LEN); / * Merger Error Description String and User Error Prefix Restriction * / WSPrintf ((LPSTR) PRBUF, "% s:% s", (lpstr) err_prefix, (lpstr) errbuf); / * Displays error text in the dialog box * / setdlgitemtext (HOURDLG, IDD_COMMENT, (LPSTR) PRBUF);} / * End wshout_err ) * // * EOF * / 3.4.3.2 WSHOUT.H list / * * file name: wstout.h * / # iFNDef _wshout_inc_ # define _wshout_inc _ / * windows 3.0 header file * / # include
16 / * global variables * / # define SOCK_DISCARD 9 / * use the UDP ttytst source port for test * / # define SOCK_SHOUT 32766 / * TCP port used for SHOUT & LISTEN * / # define BUF_SIZE 8192 # define WRITE_TIMER 1 / * function prototypes * / int Pascal Winmain (Handle, Handle, LPSTR, INT); Long Far Pascal ShoutWndProc (HWND, Word, Word, Long); Bool Far Pascal About (HWND, Word, Word, Long); Bool Far Pascal DialogProc (hwnd, WORD, WORD, LONG); BOOL FAR PASCAL Settings (HWND, WORD, WORD, LONG); BOOL InitApp (HANDLE); void CheckThisBoxOn (HWND, int); void CheckThisProtoBoxOn (HWND, int); void CheckThisProgBoxOn (HWND, int) ; void ClearBoxes (HWND); SOCKET ResolveAndConnectHost (LPSTR, HWND, int, int); SOCKET GetSocketAndBind (HWND, int, int); long UWriteData (SOCKET, HWND, int); long UReadData (SOCKET, HWND, int); long TWRITEDATA (Socket, HWnd, Int); Int ShoutBlockingHook; Int Pascal Far Wsasperror (Handle, Int, CHAR FAR *, INT); Void WSHOUT_ERR (Hwnd, Int, Char Far *); # define bcopy (a, b, c) _fmemcpy (b, a, c) char * _CALLOC (Uns IGNED, Unsigned); void _free (void *); # ifdef _cplusplus} #ndif / * __cplusplus * / # Endif / * ifndef _wshout_inc_ * // * EOF * / 3.4.3.3 WSHOUT.RC List / * * File Name: WSHOUT .RC * / # include
STYLE DS_MODALFRAME | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENUBEGIN CTEXT "Windows Shout", -1, 29, 5, 85, 8 CText "Version", -1, 46, 13, 33, 8, ss_center | ws_group ctext "Winsock.dll / N FTP Software, Inc. / Ncopyright 1993 ", Ida_copyright, 38, 40, 68, 25, SS_Center | WS_GROUP CTEXT" Version ", -1, 46, 67, 33, 8, ss_center | WS_GROUP CTEXT" NUM ", IDA_DLL_VERSION, 79 , 67, 18, 8, ss_center | WS_GROUP Control "OK", 1, "Button", BS_DEFPUSHB /TON | WS_GROUP | WS_TABSTOP, 56, 82, 32, 14 ICON "Shout", -1, 11, 8, 16, 16 Control "NUM", IDA_APP_VERSION, "Static", SS_LEFT | WS_GROUP, 79, 13, 18, 8 Control "Using", -1, "static", ss_center | WS_GROUP, 55, 26, 30, 8ENDSETTINGDIALOG DIALOG 9, 16, 172 , 117CAPTION "Settings" STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENUBEGIN CONTROL "send / recv / nBuffer & length", -1, "STATIC", SS_LEFT | WS_GROUP, 84, 8, 48, 20 CONTROL "& Port number", -1, "Static", SS_LEFT | WS_GROUP, 84, 31, 48, 10 Control "& blocking", IDS_BLOCK, "Button", BS_AUTOCHECKBOX | W S_TABSTOP, 100, 61, 56, 12 CONTROL "& TCP", IDS_TCP, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 20, 60, 41, 12 CONTROL "& Client", IDS_CLIENT, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 19, 15, 35, 12 CONTROL "& Server", IDS_SERVER, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 19, 26, 35, 12 CONTROL "& UDP", IDS_UDP, "BUTTON", BS_AUTOCHECKBOX | WS_TABSTOP, 20, 72, 41, 12 CONTROL "& Nonblocking ", IDS_NOBLOCK," Button ", BS_AUTOCHECKBOX | WS_TABSTOP, 100, 73, 56, 12 Control" OK ", IDOK,"
Button ", BS_Pushbutton | WS_TABSTOP, 40, 95, 37, 14 Control" Cancel ", IDCANCANCEL," Button ", BS_Pushbutton | WS_TABSTOP, 90, 95, 37, 14 Control", IDS_Bufflen, "Edit", ES_Center | WS_BORDER | WS_TABSTOP, 130, 11, 36, 12 Control "", IDS_Portno, "Edit", ES_Center | WS_Border | WS_TABSTOP, 130, 29, 36, 12 Control "Protocol", 237, "Button", BS_Group, 6, 49, 70 38 Control "I / O Mode", 239, "Button", BS_Groupbox, 90, 49, 70, 38 Control "Program Mode", 241, "Button", BS_GroupBox, 6, 7, 70, 34ndMainDialog Dialog 17, 32 , 163, 135CAPTION "Windows Shout" MENU MainMenuSTYLE DS_ABSALIGN | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOXBEGIN CONTROL "", IDD_HNAME, "EDIT", ES_CENTER | WS_BORDER | WS_GROUP | WS_TABSTOP, 62, 9, 93, 12 CONTROL "", IDD_WRITE, "Static", SS_Center | SS_NOPREFIX | WS_BORDER, 7, 95, 45, 11 Control "", IDD_SENT, "Static", SS_Center | WS_Border, 59, 95, 45, 11 Control ", IDD_TIME," static ", ss_center | WS_Border, 111, 95, 45, 11 Control ", IDD_Writes," static ", SS_ Center | WS_Border, 7, 120, 45, 11 Control "", IDD_BYTES, "Static", SS_Center | WS_Border, 59, 120, 45, 11 Control ", IDD_BITS," Static ", SS_Center | WS_BORDER, 111, 120, 45, 11 Control "Writes [Reads]", 105, "Static", SS_Center | WS_GROUP, 3, 85, 52, 9 Control "Writes [Reads] / S", 105, "static", ss_center | WS_GROUP, 3, 111, 55, 9 Control "Bytes", 105, "static", ss_center | WS_GROUP, 61, 85, 42, 9 Control "Bytes / Sec", 105, "Static"
, SS_Center | WS_GROUP, 61, 111, 42, 9 Control "Time (SEC)", 105, "Static", SS_Center | WS_GROUP, 111, 85, 45, 9 Control "BITS / Sec", 105, "Static", SS_CENTER | WS_GROUP, 113, 111, 42, 9 Control "Host", IDD_CoHost, "Static", SS_LEFT, 7, 10, 52, 10 Control "", IDD_Comment, "Static", SS_Center | WS_BORDER | WS_GROUP, 9, 68 , 146, 11 Control "& Start", IDOK, "Button", BS_PushButton | WS_TABSTOP, 6, 32, 32, 20 Control "Sto & P", IDCANCANCEL, "Button", BS_Pushbutton | WS_TABSTOP, 65, 32, 32, 20 Control E & XIT ", IDM_EXIT," Button ", BS_Pushbutton | WS_TABSTOP, 125, 32, 32, 20 Control", -1, "static", ss_blackframe, 0, 60, 163, 1ENDSHOUT ICON WSHOUT.ICO / * * Error Description Character Series * For WSASPERROR () function * / stringTablebegin wsabaseerr, "[0] no error" wsaeintr, "[10004] Interrupted System Call" WSAEBADF, "[10009] Bad file number" wsaeacces, "[10013] permission denied" WSAEFAULT, "[10014] Bad address" wsaeinval, "[10022] Invalid Argument" wsaemfile, " [10024] Too many open files "WSAEWOULDBLOCK," [10035] Operation would block "WSAEINPROGRESS," [10036] Operation now in progress "WSAEALREADY," [10037] Operation already in progress "WSAENOTSOCK," [10038] Socket operation on non -socket "WSAEDESTADDRREQ," [10039] Destination address required "WSAEMSGSIZE," [10040] Message too long "WSAEPROTOTYPE," [10041] Protocol wrong type for socket "WSAENOPROTOOPT," [10042] Bad protocol option "
WSAEPROTONOSUPPORT, "[10043] Protocol not supported" WSAESOCKTNOSUPPORT, "[10044] Socket type not supported" WSAEOPNOTSUPP, "[10045] Operation not supported on socket" WSAEPFNOSUPPORT, "[10046] Protocol family not supported" WSAEAFNOSUPPORT, "[10047] address family not supported by protocol family "WSAEADDRINUSE," [10048] address already in use "WSAEADDRNOTAVAIL," [10049] Can not assign requested address "WSAENETDOWN," [10050] Network is down "WSAENETUNREACH," [10051] Network is unreachable "WSAENETRESET," [10052] Net dropped connection or reset "WSAECONNABORTED," [10053] Software caused connection abort "WSAECONNRESET," [10054] Connection reset by peer "WSAENOBUFS," [10055] No buffer space available "WSAEISCONN," [10056] Socket IS Already Connected "WSAENOTCONN" [10057] Socket is not connection "wsaeshutdown," [10058] can't send after socket shutdown "wsaetoomanyrefs," [10059] TOO MANY References, can not splice "WSAETIMEDOUT," [10060] Connection timed out "WSAECONNREFUSED," [10061] Connection refused "WSAELOOP," [10062] Too many levels of symbolic links "WSAENAMETOOLONG," [10063] File name too long "WSAEHOSTDOWN, [10064] Host Is Down "WSAEHOSTUNREACH," [10065] No route to host "wsaenotempty," [10066] Directory Not Empty "WSAEPROCLIM," [10067] Too Many Processes "WSAEUSERS," [10068] Too Many Users WSAEDQUOT "[10069] disc quota exceeded"
WSAESTALE, "[10070] Stale NFS file handle" WSAEREMOTE, "[10071] Too many levels of remote in path" WSASYSNOTREADY, "[10091] Network SubSystem is unavailable" WSAVERNOTSUPPORTED, "[10092] WINSOCK DLL Version out of range" WSANOTINITIALISED , "[10093] Successful WSASTARTUP not yet performed" WSAHOST_NOT_FOUND, "[11001] Host not found" WSATRY_AGAIN, "[11002] Non-Authoritative Host not found" WSANO_RECOVERY, "[11003] Non-Recoverable errors: FORMERR, REFUSED, NOTIMP "WSANO_DATA," [11004] Valid name, no data "end / * eof * / 3.4.3.4 Ushout.c list / * * file name: ushout.c * / # include" wshout.h "/ * MSC include files: * / # include
/ * Destination machine address structure * / / * What makes shout unique is that it generates data * * in memory (as opposed to accessing the disk). * * This tests the 'raw' speed of the TCP connection * * as the rate -limiting access time is eliminated * * First, generate the data and place it into an * * array, data_buffer: * / for (counter = 0; counter % LD / N ", LTEMP; setdlgitemtext (Hourdlg, IDD_WRITES, (LPSTR) PRBUF; ltemp = bytes_sent / total_time; WSPrintf ((LPSTR) PRBUF,"% ld / n ", ltemp); setdlgitemtext (Hourdlg, IDD_BYTES, (Lpstr) PRBUF; ltemp = 8 * (bytes_sent / total_time); WSPrintf ((LPSTR) PRBUF, "% ld / n", ltemp); setdlgitemtext (HOURDLG, IDD_BITS, (LPSTR) PRBUF; / * EXIT from THE While loop * / break;} / * end if (total_time) * / write_count ; / * incr. counter = tmp; / * # of bytes placed on connections * / wsprintf ((lpstr) PRBUF, "% ld / n", bytes_sent); setdlgitemtext (HOURDLG, IDD_SENT, (LPSTR) PRBUF;} / * end if (tmp == -1) * / write_count ; / * incr. counter} Times Written * / Bytes_Sent = TMP; / * # of bytes placed on connection * / wsprintf ((lpstr) PRBUF, "% ld / n", write_count); setdlgitemtext (HOURDLG, IDD_WRITE, (LPSTR) PRBUF; WSPrintf ((lpstr) PRBUF, " % ld / n ", bytes_sent); setdlgitemtext (HOURDLG, IDD_SENT, (LPSTR) PRBUF;} / * end while * / / / / * Look for a reply ... Note: M .. Ost hosts will not give * a 'reply', done to illustrate communication between * sockets Our ulisten example will give a reply though * / SetDlgItemText (hOurDlg, IDD_COMMENT, "Waiting for reply from server ../ n"); While (1) {TMP = SIZEOF (DEST); i_temp = recvfrom (hsock, (char far *) & replybuffer, sizeof (replybuffer), 0, (struct sockaddr *) & DEST, (INT FAR *) & TMP); if (i_temp == SOCKET_ERROR) {if (h_errno == wsaewouldblock) / * if no data, read again * / continue; else {/ * any error Besides these. Just Punt * / WSHOUT_ERR (HOURDLG, Wsagetlasterror (), " Recvfrom () ");} Break;} / * end if (i_temp == socket_error) * / / * else got a reply ... * / wsprintf ((lpstr) PRBUF," Server:% S / N ", LPSTR) ReplyBuffer; setdlgitemtext (HOURDLG, IDD_COMMENT, PRBUF); Break;} / * end while (1) * / / * all done * / return bytes_sent;} / * EOF * / 3.4.3.5 Ulisten.c List / * * File name: ulisten.c * / # include "wshout.h" / * msc incrude files: * / # include } / * end: if (errno == wsaewouldblock) * / else {if (bytes_read) {wshout_err (HOURDLG, Wsagetlasterror (), "Recvfrom ()");}} / * end else * / break;} / * end : IF (len == Socket_ERROR) * / if (btemp) {/ * to update Our main display overce * / / / * DO NOT USE WSPRINTF () or you will address an extra char * / _fmemcpy (PRBUF, INET_NTOA (Local. sin_addr), 4 * sizeof (u_long)); SetDlgItemText (hOurDlg, IDD_HNAME, (LPSTR) prbuf); SetDlgItemText (hOurDlg, IDD_COMMENT, "Reading UDP Data ..."); bTemp = FALSE;} num_reads ; if (len! = SOCKET_ERROR) bytes_read = len; / * Print the statistics gathered * / wsprintf ((LPSTR) prbuf, "% d / n", num_reads); SetDlgItemText (hOurDlg, IDD_WRITE, (LPSTR) prbuf); wsprintf ((LPSTR) PRBUF, "% ld / n", bytes_read; setdlgitemtext (HOURDLG, IDD_SENT, (LPSTR) PRBUF; TIME (& Last_time);} / * end: while * / total_time = timeout; wsprintf ((lpstr) PRBUF, "% LD / N ", TOTAL_TIME); setdlgitemtext (HOURDLG, IDD_TIME, (LPSTR) PRBUF; ltemp = num_reads / total_time; wsprintf ((LPSTR) prbuf, "% ld / n", ltemp); SetDlgItemText (hOurDlg, IDD_WRITES, (LPSTR) prbuf); ltemp = bytes_read / total_time; wsprintf ((LPSTR) prbuf, "% LD / N ", LTEMP; setdlgitemtext (Hourdlg, IDD_BYTES, (LPSTR) PRBUF); ltemp = 8 * (bytes_read / total_time); WSPrintf ((LPSTR) PRBUF,"% LD / N ", LTEMP); setdlgitemtext (HOURDLG , IDD_BITS, (LPSTR) PRBUF; if (bytes_read) {setdlgitemtext (HOURDLG, IDD_COMMENT, "... UDP Listen Done / N");} / * end: if (bytes_read) * / else {WSPRINTF ((LPSTR) PRBUF, "TIMED OUT. NO DATA Received./N"); Setdlgitemtext (HOURDLG, IDD_COMMENT, PRBUF); goto com_here;} / * end: else * / / * send reply to 'client' * / wsprintf ((lpstr) PRBUF, "Replied TO% S / N", INET_NTOA (Local. SIN_ADDR); setdlgitemtext (Hourdlg, IDD_Comment, PRBUF); for (i = 0; i <10; i) {sprintf (sendbuf, "rec'd% ld bytes./n", bytes_read); if (LEN = Sendto (HSOCK, SENDBUF, SIZEOF (STRUCT SOCKADDR FAR *) & local, sizeof (local))) {if (len == Socket_ERROR) {/ * if could not send BEC. * / if (h_errno == WSAEWOULDBLOCK) Continue; WSHOUT_ERR (Hourdlg, Wsagetlasterror (), "Sendto ()"); Break;} / * end: if (len == -1) * /} / * end: if (len = sendto () ) * /} / * End for * / com_here: return (bytes_read);} / * eof * / 3.4.3.6 TSHOUT.C List / * * File Name: TSHOUT.C * / # include "wshout.h" / * MSC include files: * / # include / * What makes shout unique is that it generates data * * in memory (as opposed to accessing the disk). * * This tests the 'raw' speed of the TCP connection * * as the rate-limiting access time is eliminated. * * First, generate the data and place it into an * * array, data_buffer: * / for (counter = 0; counter (long) DiffTime (end, start)) {/ * print the statistics GATHERED * / WSPRINTF ((LPSTR) PRBUF, "% LD / N", TOTAL_TIME); setdlgitemtext (Hourdlg, IDD_TIME, (LPSTR) PRBUF; ltemp = Write_count / total_time; WSPrintf ((LPSTR) PRBUF, "% LD / N", LTEMP; setdlgitemtext (HOURDLG, IDD_WRITES, (LPSTR) PRBUF; ltemp = bytes_sent / total_time; WSPrintf ((lpstr) PRBUF, "% LD / n ", ltemp); setdlgitemtext (HOURDLG, IDD_BYTES, (LPSTR) PRBUF; LTEMP = 8 * (Bytes_Sent / Total_Time); WSPrintf ((LPSTR) PRBUF,"% LD / N ", LTEMP); setdlgitemtext (HOURDLG, IDD_BITS , (Lpstr) PRBUF;} / * end if (total_time) * / / * all done * / setdlgitemtext (Hourdlg, IDD_Comment, "... TCP Shout Done"); returnity;} / * EOF * / 3.4. 3.7 TLISTEN.C List / * * File Name: Tlisten.c * / # include "wshout.h" / * msc incrude files: * / # include Accept (hsock, (struct socmeddr far *) & local, (int far *) & tmp);} else {for (;;) {DO {;} while (shoutblockinghook ()); / * dispatch message if any * / if ( run_cancelled) {WSASetLastError (WSAEINTR); break; / * Non-blocking mode was cancelled * /} hAcceptSock = accept (hSock, (struct sockaddr FAR *) & local, (int FAR *) & tmp); if (hAcceptSock == INVALID_SOCKET) {If (h_errno == wsaewouldblock) / * try again * /; else {/ * fatal error - Pop out. * / Break;}} / * end if ((Hacceptsock = .. * / else {/ * success - - POP out. * / Break;}} / * end for * /} / * end else * / if (Hacceptsock == invalid_socket) {WSHOUT_ERR (HOURDLG, WsageTlasterror (), "accept ()"); return 0;} / * NOW, Read The Data As Fast AS We CAN Until No more to read * / time (& Last_time); do {do {;} while (shoutblockinghook ()); / * dispatch message while available * / if (run_cancelle) { Wsasetlasterror (WSAEINTR); Break; / * Non-blocking mode Was canceled * /} Len = Recv (HacceptsoC K, readbuf, read_len, 0); if (len == socket_error) {if (h_errno == wsaewouldblock) Continue; Else Break;} else if (len == 0) Break; Num_reads ; Bytes_read = LEN; WSPRINTF LPSTR) PRBUF, "% D / N", NUM_READS; setdlgitemtext (Hourdlg, IDD_WRITE, (LPSTR) PRBUF); WSPrintf ((LPSTR) PRBUF, "% ld / n", bytes_read; setdlgitemtext (Hourdlg, IDD_SENT, LPSTR) PRBUF); if (btemp) {/ * to update Our main display overce * / / / / / / * DO NOT USE WSPRINTF () or you will add an extra char * / _fmemcpy (prBuf, inet_ntoa (local.sin_addr), 4 * SizeOf (u_long)); setdlgitemtext (Hourdlg, IDD_HNAME, (LPSTR) PRBUF; Setdlgitemtext (HOURDLG, IDD_COMMENT, "Reading TCP Data ..."); btemp = false;}} while ((Len! = 0) || (Len! = Socket_ERROR)); TIME (& now); if (len == SOCKET_ERROR) {IF ((h_errno == wsaeshutdown) || (h_errno == wsaenotconn) {/ * Nothing available forread. * / Wsprintf ((lpstr) PRBUF, "Connection from% s closed./N", INET_NTOA Local.sin_addr); setdlgitemtext (HOURDLG, IDD_COMMENT, PRBUF);} else {/ * Other Error * / WSHOUT_ERR (HOURDLG, Wsagetlasterror (), "RECV ()");}} else if (len == 0) { / * Other side shut down the connection * / wsprintf ((LPSTR) prbuf, "Connection from% s closed./n",inet_ntoa(local.sin_addr)); SetDlgItemText (hOurDlg, IDD_COMMENT, prbuf);} AcceptLinger.l_onoff = 1; AcceptLinger.l_linger = 0; ret = setsockopt (hAcceptSock, SOL_SOCKET, SO_LINGER, (char FAR *) & AcceptLinger, sizeof (AcceptLinger)); if (ret == SOCKET_ERROR) {wshout_err (hOurDlg, WSAGetLastError (), "setsockopt ( ) ");} RET = CloseSocket (HACCEPTSOCK); if (ret== socket_error) {wshout_err (Hourdlg, Wsagetlasterror (), "CloseSocket ()");} Total_time = (long) DiffTime (now, last_time); if (total_time == 0) Total_time = 1L ; / * Avoid dividing by zero * / wsprintf ((LPSTR) prbuf, "% ld / n", total_time); SetDlgItemText (hOurDlg, IDD_TIME, (LPSTR) prbuf); ltemp = num_reads / total_time; wsprintf ((LPSTR) prbuf , "% LD / N", LTEMP; setdlgitemtext (HOURDLG, IDD_WRITES, (LPSTR) PRBUF; ltemp = bytes_read / total_time; WSPrintf ((LPSTR) PRBUF, "% ld / n", ltemp); SetDlgItemText (hOurDlg, IDD_BYTES, (LPSTR) prbuf); ltemp = 8 * (bytes_read / total_time); wsprintf ((LPSTR) prbuf, "% ld / n", ltemp); SetDlgItemText (hOurDlg, IDD_BITS, (LPSTR) prbuf) ; If (bytes_read) {setdlgitemtext (HOURDLG, IDD_COMMENT, "... TCP Listen Done / N");} / * end: if (bytes_read) * / return (bytes_read);} / * EOF * / 3.4.3.8 errno .c list #include / * RETURN Length of Error String Retrieved * /} / * end wsasperror () * // * EOF * / 3.4.3.9 Resolve.c List / * * File Name: resolve.c * / # include "wshout.h" / * MSC include files: * / # include CONNECTING ... "); RET = Connect (hsock, (struct socddr far *) & dest, sizeof (dest)); if (RET == Socket_ERROR) {wshout_err (Hourdlg, WsageTlasterror ()," Connect () "); closesocket (hSock); return (SOCKET) -1;} SetDlgItemText (hOurDlg, IDD_COMMENT, "... Connected"); return hSock;} SOCKET GetSocketAndBind (HWND hOurDlg, int iProto, int iSockPort) {SOCKET hSock; / * Connection socket descriptor * / struct sockaddr_in local; / * local machine address structure * / int iSockType; extern int iTCP; extern int iUDP; / * Internet family addressing * / if (iProto == iTCP) {iSockType = SOCK_STREAM;} else {iSockType = SOCK_DGRAM;} memset (& local, '/ 0', sizeof (local)); local.sin_family = PF_INET; local.sin_port = htons ((u_short) iSockPort); / * allocate a socket descriptor * / hSock = socket (PF_INET , ISOCKTYPE, 0); if (hsock == invalid_socket) {/ * socket () failed * / wshout_err (HOURDLG, Wsagetlasterror (), "socket ()"); return (socket) -1;} / * bind socket to a local addr * / return (hsock, (struct socmeddr far *) & local, sizeof (local)); if (RET == Socket_ERROR) {/ * bind () failed * / wshout_err (HOURDLG, Wsagetlasterror (), "bind ()"); Return (socket) -1;} if (iProto == IUDP) Return (HSOCK); / * if iProto == ITCP, THEN MUST LISTEN () And Accept () Also * / RET = Listen (HSOCK, 0); / * listen on the socket * / if (Ret == Socket_ERROR) {/ * listen () failed * / wshout_err (HOURDLG, Wsagetlasterror (), "listen ()"); return (Socket) -1;} return (hsock);