windows UDP网络服务端编程 详解

引言:

  • 在使用套接字进行编程之前,无论是服务器还是客户端都必须加载Windows SOCKET动态库。函数WSAStartup就实现了此功能。它是套接字应用程序必须调用的第一个函数。可以参考:http://blog.csdn.net/ithzhang/article/details/8448655
  • Windows SOCKET可以支持多种不同的网络协议,并且提供与协议无关的编程接口。因此开发人员就可以相同的格式开发使用任一协议的网络应用程序,而不去关心各种协议的不同。
  • 每种协议都有一套不同的IP定址方案(即表示主机地址的方式)。TCP协议和UDP协议通过IP协议传输数据。
  • 关于socket编程的一些函数说明:http://patton.spaces.eepw.com.cn/articles/article/item/23229

 

一、语句解析     

  1、第一个片段:  创建套接字

SOCKET sockSrv = socket(AF_INET,SOCK_DGRAM,0);
 SOCKET socket(
  int af,      // [in] Address family specification.
  int type,    // [in] Type specification for the new socket
  int protocol // [in] Protocol to be used with the socket that is specific to the indicated address family
);
  •   Windows sockets中定义的套接字类型SOCKET来表示套接字:
    typedef unsigned int    u_int;
    typedef u_int           SOCKET;
    
    其实所谓的SOCKET的类型只不过是unsigned int的别名罢了

     

  •   Windows SOCKET通过AF_INET地址家族为IP协议定址。
    #define AF_INET         2

     

  • 网络中每台主机都有一个IP地址,用32位数字来表示。TCP和UDP必须指定端口号。在Windows SOCKET中sockaddr_in 结构被用来指定IP端口号
  • AF_INET:  AF 表示ADDRESS FAMILY 地址族;PF 表示PROTOCOL FAMILY 协议族

  2、第二个片段:为绑定地址做准备

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
  • SOCKADDR_IN 相关的解析
    typedef struct sockaddr_in SOCKADDR_IN;
    
    struct sockaddr_in{
        short               sin_family;   // Address family (must be AF_INET). 
        unsigned short        sin_port;   // IP port. 
        struct   in_addr      sin_addr;   // IP address.
        char               sin_zero[8];   // Padding to make structure the same size as SOCKADDR. 
    };
    struct in_addr {
      union {
              struct { u_char s_b1,s_b2,s_b3,s_b4; }   S_un_b;
              struct { u_short s_w1,s_w2; }            S_un_w;
              u_long                                   S_addr;
      } S_un;
    };

     

  • htonl的解析:将无符号长整型主机字节序转换为网络字节序。主机一般是低字节存储,而网络一般是高字节存储。
    htonl
    The htonl function converts a u_long from host to TCP/IP network byte order (which is big-endian).
    
    u_long htonl(
      u_long hostlong  
    );
  • htons的解析:将无符号短整型主机字节序转换为网络字节序
    htons
    The htons function converts a u_short from host to TCP/IP network byte order (which is big-endian).
    
    u_short htons(
      u_short hostshort  
    );

    相关介绍可查照:http://www.360doc.com/content/13/0624/19/12906934_295244758.shtml

  3、第三个片段:将创建的套接字与本机地址相绑定。

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

The bind function associates a local address with a socket.

int bind(
  SOCKET s,                // [in] Descriptor identifying an unbound socket.                      
  const struct sockaddr FAR *name,   // [in] Address to assign to the socket from the SOCKADDR structure. 
  int namelen                        // [in] Length of the value in the name parameter.
);

  4、第四个片段:为接收和发送信息做准备

char recvBuf[100];
char sendBuf[100];
char tempBuf[100];

SOCKADDR_IN addrClient;
int len = sizeof(SOCKADDR);

  5、相互通信,服务端首先得等待接收信息。

while (1)
    {
        recvfrom(sockSrv,recvBuf,100,0,(SOCKADDR*)&addrClient,&len);
        if ('q'==recvBuf[0])
        {
            sendto(sockSrv,"q",strlen("q")+1,0,(SOCKADDR*)&addrClient,len);
            cout << "Char end!" << endl;
            break;
        }
        sprintf(tempBuf,"%s say : %s",inet_ntoa(addrClient.sin_addr),recvBuf);
        cout << tempBuf << endl;
        cout << "please input data:" << endl;
        gets(sendBuf);
        sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&addrClient,len);
    }
  • recvfrom解析:它接收数据报和存储数据报来源的地址。
    recvfrom
    The recvfrom function receives a datagram and stores the source address.
    
    int recvfrom(
      SOCKET s,                   //[in] Descriptor identifying a bound socket. 
      char FAR* buf,              //[out] Buffer for the incoming data.           
      int len,                    //[in] Length of buf.
      int flags,                  //[in] Indicator specifying the way in which the call is made.
      struct sockaddr FAR *from,  //[out] Optional pointer to a buffer that will hold the source address upon return.
      int FAR *fromlen            //[in, out] Optional pointer to the size of the from buffer.   
    );

    sendto解析:发送数据到指定的目的地

    sendto
    The sendto function sends data to a specific destination.
    
    int sendto(
      SOCKET s,                      // [in] Descriptor identifying a (possibly connected) socket          
      const char FAR *buf,            // [in] Buffer containing the data to be transmitted           
      int len,                        // [in] Length of the data in buf       
      int flags,                      // [in] Indicator specifying the way in which the call is made       
      const struct sockaddr FAR *to,  // [in] Optional pointer to the address of the target socket
      int tolen                       // [in] Size of the address in to       
    );

    inet_ntoa解析:将网络地址转换成“.”点隔的字符串格式。详情可以参照:------>>>>点击

    inet_ntoa
    The inet_ntoa function converts an (Ipv4) Internet network address into a string in Internet standard dotted format.
    
    char FAR * inet_ntoa(
      struct   in_addr in             // [in] Structure that represents an Internet host address
    );

  6、关闭套接字,及清理套接字库

closesocket(sockSrv);
WSACleanup();

 

  • closesocket解析:关闭现存的套接字。
    closesocket
    The closesocket function closes an existing socket.
    
    int closesocket(
      SOCKET s        // [in] Descriptor identifying the socket to close
    );

    WSACleanup解析:终止,做实际的清除工作。

    WSACleanup
    The WSACleanup function terminates use of the Ws2_32.dll.
    
    int  WSACleanup (void);

     

 

posted @ 2013-06-25 10:12  aoguren  阅读(492)  评论(0)    收藏  举报