跟著webbench學C++網路程式設計(一)
阿新 • • 發佈:2020-12-21
跟著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,但是有一個巨集定義。所以雖然提示錯誤,但可以正常編譯執行。