bzero函数_端口服务getservbyname函数&getservport函数

像主机IP地址有域名一样,服务也对应着端口号,可以在/etc/service文件中查看,getservbyname函数用于给定名字和协议查找相应的服务,getservbyport函数用于根据端口号和协议查找相应的服务。

getservbyname函数原型:

#include <netdb.h>

struct servent *getservbyname(const char *name, const char *proto);

struct servent {
    char  *s_name;       /* 服务名 */
    char **s_aliases;    /* 别名 */
    int    s_port;       /* 端口号,网络字节序 */
    char  *s_proto;      /* 协议 */
}

getservbyport函数原型:

struct servent *getservbyport(int port, const char *proto);
/* port 参数是网络字节序 */

运行本地daytime服务器,然后跑daytimetcpcli1程序,运行结果如下:

6902163924a3e9803c42932a1868347c.png

测试h3c是否开启daytime服务,运行结果如下:

59b2fff7b89aeee5b39da5a38cc2fe04.png
#include    "unp.h"

int
main(int argc, char **argv)
{
    int                 sockfd, n;
    char                recvline[MAXLINE + 1];
    struct sockaddr_in  servaddr;
    struct in_addr      **pptr;
    struct in_addr      *inetaddrp[2];
    struct in_addr      inetaddr;
    struct hostent      *hp;
    struct servent      *sp;

    if (argc != 3)
        err_quit("usage: daytimetcpcli1 <hostname> <service>");

    if ( (hp = gethostbyname(argv[1])) == NULL) {
        if (inet_aton(argv[1], &inetaddr) == 0) {
            err_quit("hostname error for %s: %s", argv[1], hstrerror(h_errno));
        } else {
            inetaddrp[0] = &inetaddr;
            inetaddrp[1] = NULL;
            pptr = inetaddrp;
        }
    } else {
        pptr = (struct in_addr **) hp->h_addr_list;
    }

    if ( (sp = getservbyname(argv[2], "tcp")) == NULL)
        err_quit("getservbyname error for %s", argv[2]);

    for ( ; *pptr != NULL; pptr++) {
        sockfd = Socket(AF_INET, SOCK_STREAM, 0);

        bzero(&servaddr, sizeof(servaddr));
        servaddr.sin_family = AF_INET;
        servaddr.sin_port = sp->s_port;
        memcpy(&servaddr.sin_addr, *pptr, sizeof(struct in_addr));
        printf("trying %sn",
               Sock_ntop((SA *) &servaddr, sizeof(servaddr)));

        if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) == 0)
            break;      /* success */
        err_ret("connect error");
        close(sockfd);
    }
    if (*pptr == NULL)
        err_quit("unable to connect");

    while ( (n = Read(sockfd, recvline, MAXLINE)) > 0) {
        recvline[n] = 0;    /* null terminate */
        Fputs(recvline, stdout);
    }
    exit(0);
}

程序需要2个参数,一个主机名,一个服务名。

  • 如果主机名是域名的话,那么走域名解析gethostbyname ,拿到IPv4地址网络序
  • 如果主机名是IP地址的话,那么走IPv4地址网络序inet_aton

getservbyname获取服务网络序端口号,尝试socket连接每个服务器主机IPv4地址。如果connect连接成功,就break出循环,否则输出一个出错消息并关闭当前连接。

如果出循环没有一个connect连接成功,就退出程序。否则,读取服务器的应答,并在服务器关闭连接后终止程序(read()返回不大于0)。

参考文献:《UNIX网络编程 卷1:套接字联网API》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值