Windows Socket API

Source: Internet
Author: User
Tags ftp protocol htons

Windows Socket API usage experience
This article is some of my experiences in MS-windows and HP-UNIX network programming. It is for your reference only. If the socket function mentioned in this article is not specifically described, it refers to the Windows Socket API.
1. wsastartup Function
Int wsastartup (
Word wversionrequested,
To use a socket program, you must call the wsastartup function before using the socket. The first parameter of this function indicates the socket version requested by the program. The high byte indicates the secondary version and the low byte indicates the primary version; the operating system uses the second parameter to return the request's socket version. When an application calls the wsastartup function, the operating system searches for the corresponding socket Library Based on the requested socket version, and then binds the socket Library to the application. In the future, the application can call its socket function in the requested socket library. After the function is successfully executed, 0 is returned.
For example, if a program uses a socket of Version 2.1, the program code is as follows:
Wversionrequested = makeword (2, 1 );
Err = wsastartup (wversionrequested, & wsadata );

Ii. wsacleanup Function
Int wsacleanup (void );
After the application completes the use of the requested socket library, it needs to call the wsacleanup function to unbind from the socket library and release the system resources occupied by the socket library.

Iii. Socket Functions
Socket socket (
Int AF,
Int type,
Int Protocol
The application calls the socket function to create a socket capable of network communication. The first parameter specifies the protocol family used by the application. For the TCP/IP protocol family, this parameter is set to pf_inet. The second parameter specifies the socket type to be created, the stream connection type is sock_stream, And the datagram socket type is sock_dgram. The third parameter specifies the communication protocol used by the application.
This function returns the descriptor of the newly created socket if the call is successful, and invalid_socket if the call fails. The socket descriptor is an integer value. Each process has a socket Descriptor Table in the process space, which stores the correspondence between the socket Descriptor and the socket data structure. In this table, one field stores the descriptor of the newly created socket, and the other field stores the address of the socket data structure. Therefore, the corresponding socket data structure can be found based on the socket descriptor. Each process has a socket Descriptor Table in its own process space, but the socket data structure is in the kernel buffer of the operating system. The following is an example of creating a stream socket:
Struct protoent * PPE;
PPE = getprotobyname ("TCP ");
Socket listensocket = socket (pf_inet, sock_stream, PPE-> p_proto );

Iv. closesocket Functions
Int closesocket (
Socket s
The closesocket function is used to close a socket whose descriptor is S. Each process has a socket Descriptor Table. Each socket descriptor in the table corresponds to a socket Data Structure located in the operating system buffer, therefore, several socket descriptors may point to the same socket data structure. There is a field in the socket data structure that stores the number of times this structure is referenced, that is, how many socket descriptors point to this structure. When the closesocket function is called, the operating system first checks the value of this field in the socket data structure. If it is 1, it indicates that only one socket descriptor points to it, therefore, the operating system first clears the entry corresponding to S in the socket Descriptor Table and releases the socket data structure corresponding to S. If this field is greater than 1, then, the operating system only clears the corresponding table items of S in the socket Descriptor Table, and reduces the number of references to the socket data structure of S by 1.
If the closesocket function is successfully executed, 0 is returned; otherwise, socket_error is returned.

5. Send Function
Int send (
Socket s,
Const char far * Buf,
Int Len,
Int flags
It doesn't matter whether the client or server application uses the send function to send data to the other end of the TCP connection. The client program generally uses the send function to send requests to the server, while the server sends responses to the client program by using the send function. The first parameter of this function specifies the sender socket descriptor. The second parameter specifies a buffer zone for storing data to be sent by the application. The third parameter specifies the number of bytes of data to be sent; the fourth parameter is usually set to 0. Only the execution process of the send function for Synchronous socket is described here. When this function is called, send first compares the length of the data to be sent Len and the length of the sending buffer of socket s. If Len is greater than the length of the sending buffer of S, the function returns socket_error; if Len is smaller than or equal to the length of the sending buffer of S, send first checks whether the protocol is sending data in the sending buffer of S. If yes, wait for the Protocol to finish sending the data, if the Protocol has not started sending data in the sending buffer of S or there is no data in the sending buffer of S, send will compare the remaining space in the sending buffer of S and Len, if Len is larger than the size of the remaining space, send will wait for the Protocol to finish sending data in the s sending buffer, if Len is smaller than the size of the remaining space, send only copies the data in the Buf to the remaining space (note that it is not sending the data in the sending buffer of S to the other end of the connection, instead, send only copies the data in the Buf to the remaining space in the sending buffer of S ). If the send function successfully copies the data, the actual number of bytes of copy is returned. If an error occurs during sending data copy, the send function returns socket_error; if the network is disconnected when sending data while waiting for the Protocol to send data, the send function also returns socket_error. Note that the send function successfully copies the data in the Buf to the remaining space of the s sending buffer, and then returns the data. However, the data is not necessarily uploaded to the other end of the connection immediately. If a network error occurs during subsequent transmission, the next socket function will return socket_error. (Each socket function except send must wait for the data in the socket sending buffer to be transmitted by the protocol before execution. If a network error occurs while waiting, then the socket function will return socket_error)
Note: In Unix systems, if the network is disconnected when sending data while waiting for the send protocol, the process that calls send receives a sigpipe signal. The process processes the signal by default and terminates the process.

Vi. Recv Functions
Int Recv (
Socket s,
Char far * Buf,
Int Len,
Int flags
It doesn't matter whether the client or server application uses the Recv function to receive data from the other end of the TCP connection. The first parameter of the function specifies the receiver socket descriptor. The second parameter specifies a buffer zone, which is used to store the data received by the Recv function. The third parameter specifies the length of the Buf; the fourth parameter is usually set to 0. Only the execution process of the Recv function for Synchronous socket is described here. When the application calls the Recv function, the Recv waits for the data in the s sending buffer to be transmitted by the Protocol. If the Protocol sends data in the s sending buffer, a network error occurs, then the Recv function returns socket_error. If no data is in the sending buffer of s or the data is successfully sent by the protocol, the Recv first checks the receiving buffer of socket S, if there is no data in the s receiving buffer or the Protocol is receiving data, the Recv waits until the Protocol receives the data. When the Protocol receives the data, the Recv function copies the data in the s receiving buffer to the Buf (note that the data received by the protocol may be larger than the length of the Buf, in this case, you need to call the Recv function several times to copy the data in the s receiving buffer. The Recv function only copies data, and the real data reception is completed by the Protocol). The Recv function returns the actual number of bytes of the copy. If a Recv error occurs during copy, socket_error is returned. If the Recv function is interrupted while waiting for the Protocol to receive data, 0 is returned.
Note: In Unix systems, if the network is disconnected when the Recv function is waiting for the Protocol to receive data, the process that calls the Recv will receive a sigpipe signal, the process processes this signal by default.

VII. Bind Functions
Int BIND (
Socket s,
Const struct sockaddr far * Name,
Int namelen
After a socket is created, the data structure of the socket contains a default IP address and a default port number. A service program must call the BIND function to bind an IP address and a specific port number to it. Generally, a customer program does not need to call the BIND function to bind an IP address and a disconnected slogan to its socket. The first parameter of the function specifies the socket descriptor to be bound. The second parameter specifies a sockaddr structure, which is defined as follows:
Struct sockaddr {
U_short sa_family;
Char sa_data [14];
Sa_family specifies the address family. For sockets in the TCP/IP protocol family, set af_inet. When binding a socket in the TCP/IP protocol family, we usually use another address structure:
Struct sockaddr_in {
Short sin_family;
U_short sin_port;
Struct in_addr sin_addr;
Char sin_zero [8];
Set sin_family to af_inet; sin_port to specify the port number. The sin_addr struct has only one unique field s_addr, indicating the IP address. This field is an integer and is generally used as the inet_addr () function () convert an IP address in string form to an integer of the unsigned long type and then set it to s_addr. Some servers are multi-host machines with at least two NICs. Therefore, when a service program running on such a server binds an IP address to its socket, you can set htonl (inaddr_any) to s_addr, the advantage of this is that the client program can communicate with the service program no matter which network segment. If you only bind a fixed IP address to the socket of the service program running on multiple hosts, then, only the client program that is in the same network segment as the IP address can communicate with the service program. We use 0 to fill the sin_zero array to make the size of the sockaddr_in structure consistent with that of the sockaddr structure. The following is an example of a bind function call:
Struct sockaddr_in saddr;
Saddr. sin_family = af_inet;
Saddr. sin_port = htons (8888 );
Saddr. sin_addr.s_addr = htonl (inaddr_any );
BIND (listensocket, (struct sockaddr *) & saddr, sizeof (saddr ));

8. Listen Functions
Int listen (socket S, int backlog );
A service program can call the listen function to make its stream socket s in the listening state. The stream socket s in the listening status maintains a Client Connection Request queue, which can accommodate a maximum of backlog client connection requests. If the function is successfully executed, 0 is returned. If the function fails to be executed, socket_error is returned.

9. Accept Function
Socket accept (
Socket s,
Struct sockaddr far * ADDR,
Int far * addrlen
The server program calls the accept function to retrieve the first client request from the client connection request queue of the stream socket s in the listening state, create a new socket to create a connection channel with the customer socket. If the connection is successful, return the descriptor of the new socket. In the future, the new socket will exchange data with the customer socket; if it fails, invalid_socket is returned. The first parameter of the function specifies the stream socket in the listening state. The operating system uses the second parameter to return the address structure of the newly created socket; the operating system uses the third parameter to return the length of the address structure of the newly created socket. The following is an example of an Accept call:
Struct sockaddr_in serversocketaddr;
Int addrlen;
Addrlen = sizeof (serversocketaddr );
Serversocket = accept (listensocket, (struct sockaddr *) & serversocketaddr, & addrlen );

10. Connect Functions
Int connect (
Socket s,
Const struct sockaddr far * Name,
Int namelen
The customer program calls the connect function to connect the customer socket s to the service socket listening on the specific port of the Computer specified by name. If the connection is successful, connect returns 0; if the connection fails, socket_error is returned. The following is an example:
Struct sockaddr_in daddr;
Memset (void *) & daddr, 0, sizeof (daddr ));
Daddr. sin_family = af_inet;
Daddr. sin_port = htons (8888 );
Daddr. sin_addr.s_addr = inet_addr (" ");
Connect (clientsocket, (struct sockaddr *) & daddr, sizeof (daddr ));

How to Implement socket programming)
The concept of Process Communication was initially derived from a standalone system. Since each process runs within its own address range, in order to ensure that two processes communicate with each other without mutual interference and coordination, the operating system provides relevant facilities for process communication, such as pipe in unix bsd, named pipe, singal, and message in UNIX System V) shared Memory and semaphore are all used for communication between local processes. Inter-network process Communication solves the communication problem between processes on different hosts (Process Communication on the same machine can be considered as a special case ). To solve this problem, we must first solve the problem of inter-network process identification. On the same host, different processes can be uniquely identified by a process ID (PID. However, in a network environment, the process numbers assigned by each host cannot uniquely identify the process. For example, if host a assigns process number 5 to host B, process number 5 can also exist on host B. Therefore, process number 5 is meaningless. The operating system supports a large number of network protocols. Different protocols work in different ways and have different address formats. Therefore, inter-network process communication must solve the problem of multi-protocol identification. To solve the above problem, the TCP/IP Protocol introduces the following concepts.
The communication port that can be named and addressable in the network is a resource that can be allocated by the operating system. According to the description of the OSI Layer-7 protocol, the biggest difference between the transport layer and the network layer is that the transport layer provides process communication capabilities. In this sense, the final address of network communication is not only the host address, but also an identifier that can describe the process. For this reason, the concept of protocol port is proposed for TCP/IP protocol to identify the communication process.
A port is an abstract software structure, including some data structures and I/O buffers. After a process establishes a binding with a port through a system call, the data transmitted by the transport layer to the port is received by the corresponding process, the data sent from the corresponding process to the transport layer is output from this port. In TCP/IP implementation, port operations are similar to General I/O operations. A process obtains a port, which is equivalent to obtaining a local unique I/O file, it can be accessed using common read/write primitives.
Similar to file descriptors, each port has an integer descriptor called a port number to distinguish different ports. The TCP and UDP protocols of the TCP/IP transport layer are two completely independent software modules, so their respective port numbers are also independent of each other. For example, TCP has port 255 and UDP can have port 255. The two do not conflict.
Port number allocation is an important issue. There are two basic allocation methods: the first is global allocation, which is a centralized allocation method, A recognized central organization uniformly allocates the results according to user needs and publishes the results to the public. The second is local allocation, also known as dynamic connection, that is, when a process needs to access the transport layer service, submit an application to the local operating system. The operating system returns a unique local port number. Then, the process connects itself to the port through a suitable system call ). The TCP/IP Port Number is allocated in two ways. TCP/IP divides the port number into two parts. A small number of reserved ports are allocated to the service process globally. Therefore, each standard server has a globally recognized port called a secure port, which is the same even on different machines. The remaining ports are free ports and allocated locally. TCP and UDP stipulate that a port less than 256 can be used as a reserved port.
The two processes in network communication are on two different machines. In an interconnected network, two machines can be located in different networks. These networks are connected through Internet interconnection devices (gateways, bridges, and routers. Therefore, three levels of addressing are required.
1. A host is connected to multiple networks. A specific network address must be specified;
2. A host on the network should have a unique address;
3. Each process on meiyi host should have a unique identifier on the host.
The host address is an IP address. The unique identifier of a process is a sixteen-digit integer port number.
Network byte sequence
Different computers store multi-byte values in different order. Some machines store low-byte values at the starting address, while others store the opposite values. To ensure data correctness, you must specify the network byte sequence in the network protocol. The TCP/IP protocol uses the high-priced prefix format of 16-bit integers and 32-bit integers, which are included in the header file of the Protocol.
The communication link between two processes is called a connection. The connection is represented by some buffer and a set of Protocol Mechanisms internally, and the reliability is higher than that of the connectionless connection on the outside.
To sum up, a triple in the network can be globally unique as a process (protocol, local address, local port number). A triple is called a semi-correlation, it specifies each half of the connection. Full correlation
A complete inter-network process communication requires two processes, and only the same high-level protocol can be used. That is to say, TCP and UDP cannot communicate. Therefore, a complete inter-network process communication requires a quintuple:
(Protocol, local address, local port number, remote address, remote port number) Such a quintuple is called a full correlation.
In TCP/IP network applications, the main mode of interaction between two processes is the Client/Server mode, that is, the client sends a request to the server, after the server receives the request, the corresponding service Client/Server mode is established based on the following two points: first, the reason for establishing the network is that the network's software and hardware resources, computing power, and information are not equal, sharing is required to create a host with many resources to provide services, and the customer request service with few resources is not equivalent. Second, inter-network process communication is completely asynchronous. The Inter-communication process does not have a parent-child relationship, but does not share the memory buffer, therefore, a mechanism is required to establish a connection between processes that want to communicate with each other and provide synchronization for data exchange between them. This is the TCP/IP Based on the client/server mode.
The Client/Server mode adopts the active request method during the operation:
First, the server needs to start and provide corresponding services as requested:
1. Open a channel and inform the local host that it is willing to accept the customer's request on a recognized address port (port, for example, HTTP is 80.
2. Wait for the customer request to reach this port.
3. Receives a duplicate service request, processes the request, and sends a response signal. To receive concurrent service requests, activate a new process to process this customer request. The new process processes this customer request and does not need to respond to other requests. After the service is completed, close the communication link between the new process and the customer and terminate the process.
4. Return step 2, wait for another customer request
5. Disable the server.
1. Open a channel and connect to the specific port of the host where the server is located.
2. Sends a service request message to the server, waits for and receives the response, and continues to send the request.
3. The communication channel is closed and terminated after the request ends.
From the process described above, we can see that:
1. The role of client and server processes is asymmetric. Therefore, the encoding is different.
2. A service process is generally started prior to a customer request. As long as the system is running, the process persists until it is terminated normally or forcibly.

In the Unix world, there are two types of network application programming interfaces: BSD Socket socket and System v tli. since sun adopts a BSD system that supports TCP/IP, TCP/IP applications have been greatly improved. Its network application programming interface socket has become a standard in network programming. And has already entered the MS world.
TCP/IP socket provides the following three types of sockets:
1. Stream socket (socket_stream)
It provides a connection-oriented and reliable data transmission service, with data error-free, non-repeated transmission, and ordered delivery. Internal traffic control to avoid data flow exceeding the limit. Data is considered as a byte stream with no length limit. The FTP protocol uses streaming sockets.
2. Datagram socket (socket_dgram)
Provides a connectionless service. Data packets are sent in the form of independent packets. No error guarantee is provided. data may be lost or duplicated, and the receiving order is unordered. Network File System NFS uses a datagram socket.
3. Original socket (socket_raw)
This interface allows direct access to lower-level protocols, such as IP and ICMP. It is often used to verify new protocol implementations or access new devices configured in existing services.
Basic SOCKET call
Create a socket -- socket ();
Bind the local port -- BIND ();
Establish a connection -- connect (), accept ();
Listener port -- Listen ();
Data transmission-send (), Recv ();
Multiplexing of input/output -- select ();
Close socket -- closesocket ();
Regardless of the language, it is only slightly different in the format of the call group that deals with socket. I have only used C and Perl, and I don't want to show anything unrelated to Perl here. I will mainly discuss Perl socket programming below:
Create a socket:
Socket (soc_variable, domain_flag, connecttype, num) # The C language calls sockid = socket (AF, type, Protocol)
The parameter description is as follows:
Soc_variable is used to create a socket handle, which is equivalent to the sockid in C; domain_flag is called a domain tag, and in C It is equivalent to af -- address family, the address family. The address family and domain are a concept, which is actually a domain. UNIX supports the following domain types:
AF-UNIX; UNIX internal address
AF-INET; TCP/IP address
AF-NS; Xerox NS address
AF-APPLETALK; Apple's appletalk address
The domain address family supported by DOS/Windows only has AF-INET, so most socket programming only uses it.
Connecttype (type in C) is the three socket types mentioned above. Num is equivalent to the Protocol in C. once you see it, you can see that this is the Protocol number used to specify the Protocol that the socket request expects. This parameter does not necessarily work, currently, the two parameters can be set to zero.
Therefore, the establishment of a complete Perl socket is as follows:
Socket (thesck, AF-INET, socket_stream, getprotocolbyname ('tcp '));
# C language: int sockid;
# Sockid = socket (AF-INET, socket_stream, 0 );
Step 2: BIND () -- bind to the local address.
In the first step, the socket () call only specifies the Protocol element of the relevant quintuple. Additional calls are required for the other four elements. The creation of socket can be considered as creating a namespace (address family), but it is not named. BIND () binds the socket address to the socket handle (socket number in c) created on the local machine, that is, the name is assigned to the socket (handle) to specify the local semi-correlation. According to the standard socket (in the Unix world, the so-called "Standard Interface" is no different from the "C Programming Interface ), the socket address is a data structure that describes the socket address. The structure of the TCP/IP protocol address (af_inet) is as follows:
Struct sockaddr_in {
Short sin_family; // af_inet
U_short sin_port; // 16-bit port number, network byte sequence
Struct in_addr sin_addr; // 32-bit IP address, in bytes
Char sin_zero [8]; // Reserved
Other structures include sockaddr_ns and sockaddr_un, which are used for other protocol addresses. Basically, we cannot use it. Therefore, a standard binding is:
BIND (socket sockid, struct * localaddr_name, int addrlen );
// Sockid is the socket Number of An untitled socket.
// Localaddr_name is the pointer to the sockaddr_in structure used to name sockid.
// Addrlen is the byte length of localaddr_name
When using Perl BIND (), you must first call inet_aton ('localhost'); or use the inaddr_any function to obtain the IP address string, and then call
$ Localaddr_port = sockaddr_in ($ port, inet_aton ('localhost'); # $ port is the port number.
Or $ localaddr_port = sockaddr_in ($ port, inaddr_any); get the TCP/IP address, and finally BIND (server, $ localaddr_port );
Complete binding! Here, you do not need to specify the length of $ localaddr_port in bytes, which is the benefit of Perl.
These two system calls are used to complete a fully related establishment, and connect () is used to establish a connection. Accept () causes the server to wait for the actual connection from a client process. The call format is as follows:
Connect (socket sockid, struct sockaddr * destaddr, int addrlen );
// Sockid is the local socket number to establish the connection
// Destaddr is a pointer to the structure of the socket address (sink address) of the other party.
// Addrlen is the socket address length of the other party
The CONNECT () call format in Perl is:
Connect (soc_variable, name_variable)
The specific call process is as follows:
$ Remoteaddr_port = sockaddr_in ($ port, inet_aton ('abc '));
Connect (client, $ remoteaddr_port); # semi-related triple (protocol, remote address, remote port number ).
It can be found that the connect () and bind () calls are exactly the same, but the server is changed to the client, and the local is changed to remote. That's right, they have the same principle, and their functions are complementary. They have established semi-correlation between servers and clients. In this case, accept () is required to be mixed with the full correlation of a complete inter-network process communication! (In fact, standard connect () can also be used for connectionless socket calls. However, this method is relatively left-side, and people are often confused, so I won't talk about it)
Standard accept () call:
Socket newsock = accept (socket sockid, struct sockaddr * clientaddr, int addlen)
// Sockid, the local socket Number of the server
// Clientaddr, a pointer to the customer's socket structure. Its initial value is null.
// Addlen: The Byte Length of the client socket structure. Its initial value is 0.
// Newsock, the return value of accept (), is a new socket number, which can be used by the server // to process concurrent requests. The server fork is a sub-server process that uses this socket number to return
// Answer the customer request received by accept ()
It can be seen that accept () is a connection-oriented server call. It also places the client's socket address and Its byte length in clientaddr and addlen to specify the sink address for other connectionless calls. However, the connectionless usage that is flexible but not principled does not exist in Perl. The usage of Perl deems that socket must be connection-oriented. Please refer to the accept () in Perl ():
Accept (new_soc_variable, current_soc_variable );
You can see that accept () connects a client from the current socket handle to the new socket handle. The return value is the client address (sink address ). In fact, once a connection is established, the service provider does not need to know the sink address, as long as bit stream is instilled in the set. The advantage of this is that the Protocol is more transparent and easy to understand to applications.
Before calling accept (), you should call listen (). Listen () is used to listen on the port and receive connections. If you do not call listen (), accept () cannot be connected back to the client from the current socket. Standard listen ():
Listen (sockid, Quelen );
// Socket number. The server is willing to receive requests from it
// Quelen, the length of the Request queue, and listen () Limit the number of queued requests
Perl liste ():
Listen (soc_variable, num); # similar to the C language version
Soc_variable is the socket handle, and num is the length of the Request queue.
So far, the quintuple of a connection is all in one.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.