跟着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,但是有一个宏定义。所以虽然提示错误,但可以正常编译运行。