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

posted @ 2020-12-21 20:40  浩楠honer  阅读(178)  评论(0编辑  收藏  举报