socket步骤

  The following is a step-by-step guide to getting started with Windows Sockets programming.

  It is designed to provide an understanding of basic Winsock functions and data structures, and how they work together.

 

  • About Servers and Clients
  • Creating a Basic Winsock Application
  • Initializing Winsock
  • Creating a Socket
  • Binding a Socket
  • Listening on a Socket
  • Accepting a Connection
  • Connecting to a Socket
  • Sending and Receiving Data
  • Complete Server and Client Code

 

 

 

About Servers and Clients

   There are two distinct types of socket network applications: Server and Client. 

   Servers and Clients have different behaviors; therefore, the process of creating them is different. What follows is the general model for creating a streaming TCP/IP Server and Client.

 

Server

 

 

  1. Initialize WSA.
  2. Create a socket.
  3. Bind the socket.
  4. Listen on the socket.
  5. Accept a connection.
  6. Send and receive data.
  7. Disconnect.

Client

 

  1. Initialize WSA.
  2. Create a socket.
  3. Connect to the server.
  4. Send and receive data.
  5. Disconnect.

 

 

 

Creating a Basic Winsock Application

 

To create a basic Winsock application

 

  1. Create a new empty project.
  2. Add an empty C++ source file to the project.
  3. Ensure that the build environment refers to the Include, Lib, and Src directories of the Microsoft Platform SDK.
  4. Ensure that the build environment links to the Winsock Library file WS2_32.lib
  5. Begin programming the Winsock application. Use the Winsock API by including the Winsock 2 header file.

 

      Note  Stdio.h is used for standard input and output, specifically the printf() function.

 

[cpp] view plaincopy

  1. #include   
  2. #include "winsock2.h"  
  3.   
  4. void main() {  
  5.   return;  
  6. }  

 

 

 

 

 

Initializing Winsock

All Winsock applications must be initialized to ensure that Windows sockets are supported on the system

 

To initialize Winsock

  1  Create a WSADATA object called wsaData.

 

 

 

[cpp] view plaincopy

  1. WSADATA wsaData;  

 

  2  Call WSAStartup and return its value as an integer and check for errors.

 

[cpp] view plaincopy

  1. int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );  
  2. if ( iResult != NO_ERROR )  
  3.     printf("Error at WSAStartup()\n");  

 

 

 

Creating a Socket

After initialization, a SOCKET object must be instantiated.

 

 

[cpp] view plaincopy

  1. SOCKET m_socket;  
  2. m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );  
  3.   
  4. if ( m_socket == INVALID_SOCKET )   
  5. {  
  6.     printf( "Error at socket(): %ld\n", WSAGetLastError() );   
  7.     WSACleanup();   
  8.     return;  
  9. }  

 

 

 

 

 

Binding a Socket

  For a server to accept client connections, it must be bound to a network address within the system.

  The following code demonstrates how to bind a socket that has already been created to an IP address and port. Client applications use the IP address and port to connect to the host network.

  The sockaddr structure holds information regarding the address family, IP address, and port number

  sockaddr_in is a subset of sockaddr and is used for IP version 4 applications

 

To bind a socket

  1. Create a sockaddr_in object and set its values.

[cpp] view plaincopy

  1. sockaddr_in service;  
  2.   
  3. service.sin_family = AF_INET;  
  4. service.sin_addr.s_addr = inet_addr( "127.0.0.1" );  
  5. service.sin_port = htons( 27015 );  


     2.    Call the bind function, passing the created socket and the sockaddr_in structure as parameters. Check for general errors

 

[cpp] view plaincopy

  1. if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {  
  2.     printf( "bind() failed.\n" );  
  3.     closesocket(m_socket);  
  4.     return;  
  5. }  

 

 

 

The three lines following the declaration of sockaddr_in service are used to set up the sockaddr structure:

  • AF_INET is the Internet address family.
  • "127.0.0.1" is the local IP address to which the socket will be bound.
  • 27015 is the port number to which the socket will be bound.

 

 

 

Listening on a Socket

 

After the socket is bound to an IP address and port on the system, the server must then listen on that IP address and port for incoming connection requests

To listen on a socket

Call the listen function, passing the created socket and the maximum number of allowed connections to accept as parameters. Check for general errors.

 

[cpp] view plaincopy

  1. if ( listen( m_socket, 1 ) == SOCKET_ERROR )  
  2.     printf( "Error listening on socket.\n");  

 

 

 

 

Accepting a Connection

 

Once the socket is listening for a connection, the program must handle connection requests on that socket

To accept a connection on a socket

    1  Create a temporary SOCKET object called AcceptSocket for accepting connections.

 

[cpp] view plaincopy

  1. SOCKET AcceptSocket;  


    2 Create a continuous loop that checks for connections requests. If a connection request occurs, call the accept function to handle the request

 

 

[cpp] view plaincopy

  1. printf( "Waiting for a client to connect...\n" );  
  2. while (1) {  
  3.     AcceptSocket = SOCKET_ERROR;  
  4.     while ( AcceptSocket == SOCKET_ERROR ) {  
  5.         AcceptSocket = accept( m_socket, NULL, NULL );  
  6.     }  
  7.    


    3  When the client connection has been accepted, transfer control from the temporary socket to the original socket and stop checking for new connections

 

 

 

[cpp] view plaincopy

  1. printf( "Client Connected.\n");  
  2. m_socket = AcceptSocket;    
  3. break;  

 

 

Connecting to a Socket

 

 

 

For a client to communicate on a network, it must connect to a server.

To connect to a socket

    1  Create a sockaddr_in object clientService and set its values.

 

[cpp] view plaincopy

  1. sockaddr_in clientService;  
  2.   
  3. clientService.sin_family = AF_INET;  
  4. clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );  
  5. clientService.sin_port = htons( 27015 );  

 

    2  Call the connect function, passing the created socket and the sockaddr_in structure as parameters. Check for general errors.

 

[cpp] view plaincopy

  1. if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {  
  2.     printf( "Failed to connect.\n" );  
  3.     WSACleanup();  
  4.     return;  
  5. }  

 

 

 

The three lines following the declaration of sockaddr_in clientService are used to set up the sockaddr structure:

  • AF_INET is the Internet address family.
  • "127.0.0.1" is the remote IP address of the server that the client will connect to.
  • 27015 is the port number associated with the server that the client will connect to.

 

Sending and Receiving Data

 

 

The following code demonstrates the send and recv functions.

 

Server

 

[cpp] view plaincopy

  1. int bytesSent;  
  2. int bytesRecv = SOCKET_ERROR;  
  3. char sendbuf[32] = "Server: Sending Data.";  
  4. char recvbuf[32] = "";  
  5.   
  6. bytesRecv = recv( m_socket, recvbuf, 32, 0 );  
  7. printf( "Bytes Recv: %ld\n", bytesRecv );  
  8.   
  9. bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );  
  10. printf( "Bytes Sent: %ld\n", bytesSent );  


Client

 

[cpp] view plaincopy

  1. int bytesSent;  
  2. int bytesRecv = SOCKET_ERROR;  
  3. char sendbuf[32] = "Client: Sending data.";  
  4. char recvbuf[32] = "";  
  5.   
  6. bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );  
  7. printf( "Bytes Sent: %ld\n", bytesSent );  
  8.   
  9. while( bytesRecv == SOCKET_ERROR ) {  
  10.     bytesRecv = recv( m_socket, recvbuf, 32, 0 );  
  11.     if ( bytesRecv == 0 || bytesRecv == WSAECONNRESET ) {  
  12.         printf( "Connection Closed.\n");  
  13.         break;  
  14.     }  
  15.     if (bytesRecv < 0)  
  16.         return;  
  17.     printf( "Bytes Recv: %ld\n", bytesRecv );  
  18. }  


  In this code, two integers are used to keep track of the number of bytes that are sent and received. The send and recv functions both return an integer value of the number of bytes sent or received,respectively, or an error.

 

  Each function also takes the same parameters: the active socket, a char buffer, the number of bytes to send or receive, and any flags to use.

 

 

 

Complete Server Code

 

The following is the complete source code for the TCP/IP Server application.

[cpp] view plaincopy

  1. #include   
  2. #include "winsock2.h"  
  3.   
  4. void main() {  
  5.   
  6.     // Initialize Winsock.  
  7.     WSADATA wsaData;  
  8.     int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );  
  9.     if ( iResult != NO_ERROR )  
  10.         printf("Error at WSAStartup()\n");  
  11.   
  12.     // Create a socket.  
  13.     SOCKET m_socket;  
  14.     m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );  
  15.   
  16.     if ( m_socket == INVALID_SOCKET ) {  
  17.         printf( "Error at socket(): %ld\n", WSAGetLastError() );  
  18.         WSACleanup();  
  19.         return;  
  20.     }  
  21.   
  22.     // Bind the socket.  
  23.     sockaddr_in service;  
  24.   
  25.     service.sin_family = AF_INET;  
  26.     service.sin_addr.s_addr = inet_addr( "127.0.0.1" );  
  27.     service.sin_port = htons( 27015 );  
  28.   
  29.     if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {  
  30.         printf( "bind() failed.\n" );  
  31.         closesocket(m_socket);  
  32.         return;  
  33.     }  
  34.       
  35.     // Listen on the socket.  
  36.     if ( listen( m_socket, 1 ) == SOCKET_ERROR )  
  37.         printf( "Error listening on socket.\n");  
  38.   
  39.     // Accept connections.  
  40.     SOCKET AcceptSocket;  
  41.   
  42.     printf( "Waiting for a client to connect...\n" );  
  43.     while (1) {  
  44.         AcceptSocket = SOCKET_ERROR;  
  45.         while ( AcceptSocket == SOCKET_ERROR ) {  
  46.             AcceptSocket = accept( m_socket, NULL, NULL );  
  47.         }  
  48.         printf( "Client Connected.\n");  
  49.         m_socket = AcceptSocket;   
  50.         break;  
  51.     }  
  52.       
  53.     // Send and receive data.  
  54.     int bytesSent;  
  55.     int bytesRecv = SOCKET_ERROR;  
  56.     char sendbuf[32] = "Server: Sending Data.";  
  57.     char recvbuf[32] = "";  
  58.       
  59.     bytesRecv = recv( m_socket, recvbuf, 32, 0 );  
  60.     printf( "Bytes Recv: %ld\n", bytesRecv );  
  61.       
  62.     bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );  
  63.     printf( "Bytes Sent: %ld\n", bytesSent );  
  64.   
  65.     return;  
  66. }  

 

Complete Client Code

 

 

The following is the complete source code for the TCP/IP Client Application.

[cpp] view plaincopy

  1. #include   
  2. #include "winsock2.h"  
  3.   
  4. void main() {  
  5.   
  6.     // Initialize Winsock.  
  7.     WSADATA wsaData;  
  8.     int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );  
  9.     if ( iResult != NO_ERROR )  
  10.         printf("Error at WSAStartup()\n");  
  11.   
  12.     // Create a socket.  
  13.     SOCKET m_socket;  
  14.     m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );  
  15.   
  16.     if ( m_socket == INVALID_SOCKET ) {  
  17.         printf( "Error at socket(): %ld\n", WSAGetLastError() );  
  18.         WSACleanup();  
  19.         return;  
  20.     }  
  21.   
  22.     // Connect to a server.  
  23.     sockaddr_in clientService;  
  24.   
  25.     clientService.sin_family = AF_INET;  
  26.     clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );  
  27.     clientService.sin_port = htons( 27015 );  
  28.   
  29.     if ( connect( m_socket, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {  
  30.         printf( "Failed to connect.\n" );  
  31.         WSACleanup();  
  32.         return;  
  33.     }  
  34.   
  35.     // Send and receive data.  
  36.     int bytesSent;  
  37.     int bytesRecv = SOCKET_ERROR;  
  38.     char sendbuf[32] = "Client: Sending data.";  
  39.     char recvbuf[32] = "";  
  40.   
  41.     bytesSent = send( m_socket, sendbuf, strlen(sendbuf), 0 );  
  42.     printf( "Bytes Sent: %ld\n", bytesSent );  
  43.   
  44.     while( bytesRecv == SOCKET_ERROR ) {  
  45.         bytesRecv = recv( m_socket, recvbuf, 32, 0 );  
  46.         if ( bytesRecv == 0 || bytesRecv == WSAECONNRESET ) {  
  47.             printf( "Connection Closed.\n");  
  48.             break;  
  49.         }  
  50.         if (bytesRecv < 0)  
  51.             return;  
  52.         printf( "Bytes Recv: %ld\n", bytesRecv );  
  53.     }  
  54.   
  55.     return;  
  56. }  

你可能感兴趣的:(c++)