1. 程式人生 > 實用技巧 >跟著webbench學C++網路程式設計(一)

跟著webbench學C++網路程式設計(一)

跟著webbench學C++網路程式設計(一)

​ 最近看了c++網路程式設計的基礎知識,現在結合一些專案來深入學習。由淺入深,先從網路測試工具webbench開始學習。

​ webbech的原始碼,主要是兩個檔案,一個是socket.c,一個是webbench.c。先從簡單的socket.c開始。socket.c的程式碼如下:

/* $Id: socket.c 1.1 1995/01/01 07:11:14 cthuang Exp $
 *
 * This module has been modified by Radim Kolar for OS/2 emx
 */
 
/***********************************************************************
  module:       socket.c
  program:      popclient
  SCCS ID:      @(#)socket.c    1.5  4/1/94
  programmer:   Virginia Tech Computing Center
  compiler:     DEC RISC C compiler (Ultrix 4.1)
  environment:  DEC Ultrix 4.3 
  description:  UNIX sockets code.
 ***********************************************************************/
 
#include <sys/types.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/time.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
 
int Socket(const char *host, int clientPort)
{
    int sock;
    unsigned long inaddr;	
    struct sockaddr_in ad;
    struct hostent *hp;
 
    /* 零填充初始化 */
    memset(&ad, 0, sizeof(ad));
    ad.sin_family = AF_INET;
 
    /* 通過inet_addr函式將點分十進位制字串表示的IPV4地址轉化為網路位元組序整數表示的IPv4地址 */
    inaddr = inet_addr(host);
    if (inaddr != INADDR_NONE)
        memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
    /* 如果輸入是域名,則使用gethostbyname查詢相關資訊並填寫 */
    else
    {
        hp = gethostbyname(host);
        if (hp == NULL)
            return -1;
        memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
    }
    /* htons:host to network short,將主機位元組序轉換為網路位元組序 */
    ad.sin_port = htons(clientPort);
 
    /* 建立 socket */
    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0)
        return sock;
    /* 建立連結 */
    /* 所有專用socket地址(這裡的socketaddr_in)型別的變數在實際是使用時,都需要強制轉換為通用socket地址型別sockaddr,因為所有的socket程式設計介面使用的地址引數型別都是socketaddr */
    if (connect(sock, (struct sockaddr *)&ad, sizeof(ad)) < 0)
        return -1;
    return sock;
}

​ 這段程式碼主要的作用是定義了一個函式,對傳入的地址和埠建立一個連線。

​ 除了上面程式碼中的註釋部分,還要注意的是,編譯器可能會報這樣的錯:

'struct hostent' has no member named 'h_addr'

這其實不是一個錯誤,看一下hostent結構體的定義:

/* Description of data base entry for a single host. */
struct hostent
{
  char *h_name;         	/* Official name of host.	規範名 */
  char **h_aliases;     	/* Alias list.				別名 */
  int h_addrtype;       	/* Host address type.		IP地址型別:ipv4、ipv6 */
  int h_length;         	/* Length of address.		主機的IP地址長度 */
  char **h_addr_list;       /* List of addresses from name server. 主機的IP地址,以網路位元組序儲存*/
# define h_addr h_addr_list[0] /* Address, for backward compatibility.*/
};

可以 看到雖然hostent結構體裡沒有直接定義 h_addr,但是有一個巨集定義。所以雖然提示錯誤,但可以正常編譯執行。