1. 程式人生 > >使用基本的socket函數

使用基本的socket函數

socket clu socket函數 主機信息 nbsp 可用 5.1 ipv 文件

1.socket庫的2.2版本的文件:

  dll文件:ws2_32.dll

  lib文件:ws2_32.lib

  頭文件:<WINSOCK2.H>

2.socket庫的初始化和卸載

  2.1-初始化socket庫

    int WSAStartup (

  WORD wVersionRequested, //請求使用的庫的版本

LPWSADATA lpWSAData //返回可用的庫的信息

    );

  2.2-卸載socket庫

    WSACleanup();

  2.3-MFC提供了一個AfxSocketInit函數,該函數內部自動調用了WSAStartup函數和WSACleanup函數,利用該函數加載和卸載socket庫時,不需要為工程連接ws2_32.lib庫文件,僅需包含頭文件:#include <Afxsock.h>,且必須在應用的程序類的InitInstance函數中調用該函數,該函數加載的是1.1版本的socket庫;

    BOOL AfxSocketInit( WSADATA* lpwsaData = NULL );

    返回值:函數調用成功返回非0值,調用失敗返回0;

3.TCP通信

  3.1-TCP服務器

    1--創建服務器端socket

      SOCKET socket (int af, int type, int protocol);

        af:指定地址族,AF_UNIX/AF_LOCAL/AF_FILE--本地通信;AF_INET--網絡通信IPv4(主用);AF_INET6--網絡通信IPv6(前綴AF替換成PF效果一樣);

        type:指定socket類型,SOCK_STREAM--流式套接字,SOCK_DGRAM--數據報式套接字;

        protocol:推薦為0;

      函數返回值:成功返回socket描述符;失敗返回一個INVALID_SOCKET值,錯誤信息可通過WSAGetLastError函數返回;

    2--綁定IP地址和端口(bind)

      int bind (SOCKET s, const struct sockaddr FAR* name, int namelen);

        s:要綁定的套接字;

        name:指定該套接字的通信地址信息,指向sockaddr結構體或sockaddr_un結構體或sockaddr_in結構體的指針變量;

        nameLen:指定地址結構的長度;

      函數返回值:成功返回0;失敗返回一個SOCKET_ERROR,錯誤信息可通過WSAGetLastError函數返回;

      通信地址包括結構體:

        struct sockaddr --主要用於做函數的參數,不負責存儲數據;

          struct sockaddr {

          unsigned short sa_family; //指定地址族

           char sa_data[14]; //要求一塊內存分配區,起占位作用

          };

        struct sockaddr_in --負責存儲網絡通信的地址數據

          struct sockaddr_in{

           short sin_family; //指定地址族

           unsigned short sin_port; //端口號

          struct in_addr sin_addr; //主機IP地址

          char sin_zero[8];

          };

          註:若本地機器具有多個網卡,則每個網卡均有自己的IP地址,可將IP地址指定為INADDR_ANY,允許向分配給本地機器的各個IP地址發送或接收數據;

    3--監聽(listen)

      int listen ( SOCKET s, int backlog );

        s:套接字;

        backlog:SOMAXCONN,設置等待隊列的最大長度(可接收的請求個數);

    4--等待客戶端連接並接受(accept)

      SOCKET accept ( SOCKET s, struct sockaddr FAR* addr, int FAR* addrlen );

        s:套接字;

        addr:指向一個緩沖區,該緩沖區用來保存服務器端接受的發起連接的客戶端的IP地址信息和端口信息;

        addrlen:返回包含地址信息的長度;

      函數返回值:成功返回socket描述符;失敗返回一個INVALID_SOCKET值,錯誤信息可通過WSAGetLastError函數返回;

    5--數據收發(send/recv)

      int send ( SOCKET s, const char FAR * buf, int len, int flags );

        s:套接字;

        buf:指向一個緩沖區,該緩沖區包含將要傳遞的數據;

        len:緩沖區的長度;

        flags:設為0;

      int recv ( SOCKET s, char FAR* buf, int len, int flags );

        s:套接字;

        buf:指向一個緩沖區,用來保存接收的數據;

        len:緩沖區的長度;

        flags:設為0;

    6--關閉socket

      int closesocket ( SOCKET s );

    通過netstat -an,查看網絡端口狀態

  

  3.2-TCP客戶端

    1--創建客戶端socket

    2--連接服務器,如果是本機 inet_addr("127.0.0.1");

      int connect ( SOCKET s, const struct sockaddr FAR* name, int namelen );

        s:套接字;

        name:設定連接的服務器端地址信息;

        namelen:指定服務器端地址的長度;

    3--數據收發(send/recv)

    4--關閉socket

4.UDP通信

  4.1-UDP服務器

    1--創建服務器端socket

    2--綁定IP地址和端口(bind)

    3--數據收發 recvfrom/sendto

      int recvfrom ( SOCKET s, char FAR* buf, int len, int flags, struct sockaddr FAR* from, int FAR* fromlen );

        s:套接字;

        buf:指向一個緩沖區,用來接收數據;

        len:緩沖區的長度;

        flags:設為0;

        from:指向地址結構體,用來接收發送數據方的地址信息;

        fromlen:調用前須給一個初始值,函數調用後會返回地址結構的大小;

      int sendto ( SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR * to, int tolen );

        s:套接字;

        buf:指向一個緩沖區,包含將要發送的數據;

        len:指定緩沖區中數據的長度;

        flags:設為0;

        to:可選指針,指定目標套接字的地址;

        tolen:參數to指定的地址的長度;

    4--關閉socket

  4.2-UDP客戶端

    1--創建客戶端socket

    2--數據收發 sendto/recvfrom

    3--關閉socket

5.IP地址格式和端口格式的轉換

  5.1-IP地址格式的轉換

    將點分十進制的IP地址轉為十六進制的格式:

      unsigned long inet_addr ( const char FAR * cp );

    將IP地址從十六進制轉為點分十進制的格式:

      char FAR * inet_ntoa ( struct in_addr in );

  5.2-端口格式的轉換

    將本機端口的整數格式轉為TCP/IP網絡整數格式:

      u_short htons ( u_short hostshort ); //16位

      u_long htonl ( u_long hostlong ); //32位

    將端口的網絡整數格式轉為本地端口的整數格式:

      u_short ntohs ( u_short netshort );

  5.3-主機名<-->IP地址

    5.3.1主機名轉換為IP地址

      函數gethostbyname從主機數據庫中獲取主機名相對應的IP地址;

      struct hostent FAR * gethostbyname ( const char FAR * name );

        name:指向一個主機名字符串;

      返回值:函數返回hostent結構體類型的指針,該結構體類型的定義如下:

        struct hostent {

         char FAR * h_name;

         char FAR * FAR * h_aliases;

         short h_addrtype;

         short h_length;

         char FAR * FAR * h_addr_list;

        };

        該結構體的最後一個成員h_addr_list是一個指針數組,它的每個元素都是一個字符指針,指向內存中存放的一個個點分十進制表示的主機IP地址,一臺主機可能會有多個IP地址;

    5.3.2IP地址轉換為主機名

      函數gethostbyaddr將根據指定的IP地址獲取相應的主機信息;

      struct HOSTENT FAR * gethostbyaddr (

         const char FAR * addr,

         int len,

         int type

      );

          addr:是一個指向點分十進制類型的IP地址的指針;

          len:地址長度;對於AF_INET地址族,長度必須為4個字節;

          type:地址類型,Windows平臺下必須設為AF_INET;

      返回值:函數也是返回hostent結構體類型的指針,結構體中的h_name數據成員就是主機名;

使用基本的socket函數