Windows Socket API Programming Example __ programming

Source: Internet
Author: User
Tags terminates htons

Windows Socket API Programming Examples

Has 408 reading 2010-05-19 13:50

fromFind a simple demo on the Internet:

First look at the server-side program:

#include <winsock2.h>
#include <iostream>
using namespace Std;
#define Port_server 6666//Custom Port 6666
#define Num_clients 10
#pragma comment (lib, "Ws2_32.lib")

int main (int argc, char* argv[])
{
cout << "Start server ..." << Endl;

Wsadata Wsadata;
WORD sockversion = Makeword (2, 0);
if (0!= WSAStartup (sockversion, &wsadata))
{
/*
A program using the socket must call the WSAStartup function before using the socket. The first parameter of the function indicates the version of the socket that the program requests to use, where the high byte indicates the secondary version, the low byte indicates the major version, and the operating system uses the second parameter to return the version information of the requested socket. When an application calls the WSAStartup function, the operating system searches for the corresponding socket library based on the requested version of the socket, and then binds the found socket library to the application. The application can then invoke the other socket functions in the requested socket library. The function returns 0 after successful execution.
*/
cout << "Failed to retrive socket version."
<< Endl;
return 0;
}
SOCKET Sock_sev;
Sock_sev = socket (af_inet, sock_stream, ipproto_tcp);
/*
The application calls the socket function to create a socket that can communicate on the network. The first parameter specifies the protocol family of the communication protocol used by the application, and for the TCP/IP protocol family, the parameter is set to Pf_inet; The second parameter specifies the type of socket to create, the stream socket type is sock_stream, and the datagram socket type is SOCK_DGRAM The third parameter specifies the communication protocol used by the application. The function returns the descriptor of the newly created socket if the call succeeds, and returns Invalid_socket if it fails. A socket descriptor is a value of an integer type. There is a Socket descriptor table in the process space of each process, which holds the corresponding relationship between the socket descriptor and the socket data structure. There is a field in the table that holds the descriptor for the newly created socket, and the other field holds the address of the socket data structure, so that its corresponding socket data structure can be found based on the socket descriptor. Each process has a socket descriptor in its own process space, but the socket data structure is in the kernel buffer of the operating system.
*/
if (Invalid_socket = = Sock_sev)
{
cout << "Invalid socket." << Endl;
WSACleanup ();
/*
After the application completes the use of the requested socket library, it calls the WSACleanup function to unbind the socket library and free the system resources occupied by the socket library.
*/
return 0;
}
Sockaddr_in Addr_sev;
addr_sev.sin_family = af_inet;
Addr_sev.sin_port = htons (port_server);
ADDR_SEV.SIN_ADDR.S_ADDR = Inaddr_any;
if (Socket_error = = Bind (Sock_sev, (SOCKADDR *) &addr_sev, sizeof (Addr_sev))
{
/*
When a socket is created, there is a default IP address and a default port number in the socket data structure. A service program must call the BIND function to bind it to an IP address and a specific port number. Typically, a client does not have to call the BIND function to bind its socket to an IP address and a broken number.
When tying a socket to a TCP/IP protocol family, we usually use the address structure:
struct SOCKADDR_IN {
Short sin_family;
U_short Sin_port;
struct IN_ADDR sin_addr;
Char Sin_zero[8];
};
Where the sin_family set af_inet;sin_port indicates the port number; SIN_ADDR structure body only has a unique field s_addr, which represents an IP address, which is an integer, generally using a function inet_ Addr () converts an IP address in the form of a string to an integer value of unsigned long and then to S_ADDR. Some servers are multihomed hosts, with at least two network adapters, the service program running on such a server can place htonl (inaddr_any) to s_addr when it binds an IP address to its socket, the benefit of which is that clients on any network segment can communicate with the service program If only a fixed IP address is bound to the socket running on the multihomed host, then only the client program that is on the same network segment as the IP address can communicate with the service program. We populate the Sin_zero array with 0来, so that the SOCKADDR_IN structure is the same size as the SOCKADDR structure.
*/
cout << "Failed to bind." << Endl;
WSACleanup ();
return 0;
}
if (Socket_error = = Listen (Sock_sev, num_clients))
{
/*
The service program can invoke the Listen function to make its stream socket s in a listening state. The streaming socket s in the listening state maintains a client connection request queue that accommodates up to backlog client connection requests. Returns 0 if the function succeeds, or returns SOCKET_ERROR if execution fails.
*/
cout << "Failed to listen." << Endl;
WSACleanup ();
return 0;
}

SOCKET sock_client;
Sockaddr_in addr_client;
int naddrlen = sizeof (addr_client);
while (true)
{
Char tmp[512];
Sock_client = Accept (Sock_sev, (SOCKADDR *) &addr_client, &naddrlen);
/*
The service program calls the Accept function to take out one of the top customer requests from the Client connection request queue of the streaming socket s in the listening state. and creates a new socket to create a connection channel with the client socket, and if the connection succeeds, returns a descriptor for the newly created socket. Later, the newly created socket is exchanged with the client socket, and Invalid_socket is returned if it fails. The first parameter of the function specifies a 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.
*/
if (Invalid_socket = = sock_client)
{
cout << "Failed to accept." << Endl;
Continue
}
sprintf (tmp, "Your IP is%s/n", Inet_ntoa (ADDR_CLIENT.SIN_ADDR));
Send (Sock_client, TMP, STRLEN (TMP), 0);
/*
Both the client and the server application use the Send function to send data to the other end of the TCP connection. The client typically sends a request to the server using the Send function, and the server usually sends a response to the client using the Send function. The first parameter of the function specifies the sending-end socket descriptor, the second parameter indicates a buffer in which the application will send data, and the third parameter indicates the number of bytes of data to be sent, and the fourth parameter is typically 0. This only describes the execution flow of the Send function for synchronous sockets. When the function is called, send first compares the length of the send buffer for the data to be sent, and if Len is greater than the length of the send buffer of s, the function returns SOCKET_ERROR; If Len is less than or equal to the length of the send buffer of s, then Send first checks to see if the protocol is sending data in the send buffer of S. If it is waiting for the protocol to send the data, if the protocol has not started sending the data in the send buffer of s or the send buffer of S has no data, then send compares the remaining space of the send buffer of S and Len, If Len is larger than the remaining space, send waits until the protocol sends the data from the send buffer of s, and if Len is less than the remaining space, send only the data in the BUF to the rest of the space (note that not send sends the data from the send buffer of s to the other end of the connection) Instead, the protocol sends only the data in the BUF to the rest of the send buffer of S. If the Send function copy data succeeds, it returns the actual copy of the number of bytes, if the send in the copy data error, then send back to socket_error; if send is waiting for the protocol to transfer data when the network disconnected, then the Send function also returned Back to Socket_error. Note that the Send function returns when the data in buf succeeds in the remaining space of the send buffer of s, but the data is not necessarily immediately uploaded to the other end of the connection. The next socket function returns SOCKET_ERROR if the protocol has a network error during subsequent transmissions. (each except send the SOCKET function at the beginning of the first always wait for the socket to send the buffer data sent by the Protocol to continue, if there is a network error waiting, then the socket function will return to SOCKET_ERROR)
Note: On UNIX systems, if send is disconnected while waiting for the protocol to transfer data, the process calling send receives a sigpipe signal, and the process terminates the process by default.
*/
cout << "Connection from" << Inet_ntoa (ADDR_CLIENT.SIN_ADDR)
<< Endl;
Closesocket (sock_client);
/*
The Closesocket function is used to close a descriptor to the s socket. Because there is a socket descriptor in each process, each socket descriptor in the table corresponds to a socket data structure in the operating system buffer, so it is possible to have several socket descriptors pointing to the same socket data structure. In a socket data structure there is a special field that holds the number of references to the structure, that is, how many socket descriptors are pointing to that structure. When the Closesocket function is called, the operating system first checks the value of the field in the socket data structure. If 1, it means that only one socket descriptor points to it, so the operating system clears the corresponding table entry for s in the socket descriptor table and releases the corresponding socket data structure If the field is greater than 1, then the operating system clears only the corresponding table entry in the Socket descriptor table for s, and the number of references to the socket data structure of s corresponds to minus 1.
The Closesocket function returns 0 if the execution succeeds, otherwise it returns SOCKET_ERROR.
*/
}

return 0;
}


Then look at the client program:
#include <winsock2.h>
#include <iostream>
using namespace Std;
#define Port_server 6656
#pragma comment (lib, "Ws2_32.lib")

int main (int argc, char* argv[])
{
cout << "Start up TCP client." << Endl;

Wsadata Wsadata;
WORD sockversion = Makeword (2, 0);
if (0!= WSAStartup (sockversion, &wsadata))
{
cout << "Failed to retrive socket version."
<< Endl;
return 0;
}

SOCKET sock_client;
Sock_client = socket (af_inet, sock_stream, ipproto_tcp);
if (Invalid_socket = = sock_client)
{
cout << "Invalid socket." << Endl;
WSACleanup ();
return 0;
}
Sockaddr_in Addr_sev;
addr_sev.sin_family = af_inet;
Addr_sev.sin_port = htons (port_server);
ADDR_SEV.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1");
if (Socket_error = Connect (sock_client, (SOCKADDR *) &addr_sev, sizeof (Addr_sev))
{
/*
The client invokes the Connect function to connect the customer socket s with the service socket on the specific port on the computer specified by name. Connect returns 0 if the connection succeeds, and returns SOCKET_ERROR if it fails.
*/
cout << "Failed to connect." << Endl;
WSACleanup ();
return 0;
}
Char buf[512];
int recv_size = 0;
Recv_size = recv (sock_client, BUF, 512, 0);
/*
Both the client and the server application receive data from the other end of the TCP connection using the Recv function. The first parameter of the function specifies the receiver socket descriptor, and the second parameter indicates a buffer that holds the data received by the RECV function, the third parameter indicates the length of the buf, and the fourth parameter is typically 0. This only describes the execution flow of the recv function of the synchronous socket. When the application calls the Recv function, recv waits for the data in the send buffer of s to be transmitted by protocol, and if the protocol has a network error transmitting the data in the send buffer of S, then the RECV function returns SOCKET_ERROR, If there is no data in the send buffer of s, or the data is successfully sent by the protocol, recv first checks the socket s receive buffer, if the s receive buffer has no data or the protocol is receiving data, then the recv waits until the protocol receives the data. When the protocol has received the data, the RECV function will copy the data from the receive buffer of S to the BUF (note that the protocol receives more data than the BUF length, so it is necessary to invoke several recv functions in this case to copy the data in the receive buffer of S. The recv function is just copy data, and the true receive data is protocol to complete, and the Recv function returns the actual number of bytes of copy. If recv fails at copy, it returns SOCKET_ERROR, which returns 0 if the Recv function is interrupted while waiting for the protocol to receive data.
Note: On UNIX systems, if the RECV function is disconnected while waiting for the protocol to receive data, the process calling recv receives a sigpipe signal, and the process terminates the process by default.
*/
if (> Recv_size)
{
Buf[recv_size] = '/0 ';
cout << "Receive data is:" << buf << Endl;
memset (buf, 0, sizeof (BUF));
}
Else
{
cout << "Receive data is overflow" << Endl;
}
Closesocket (sock_client);
WSACleanup ();
System ("PAUSE");
return 0;
}

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: info-contact@alibabacloud.com 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.