unix网络基础-TCP时间获取客户程序

本文详细解析了《UNIX网络编程卷1:套接字API》中的intro/daytimetcpcli.c示例代码,该客户端通过TCP连接获取服务器的当前时间和日期。文章介绍了代码的关键部分,包括连接函数、地址转换、数据读取和显示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TCP时间获取客户程序

从今天开始学习一下《UNIX网络编程卷1:套接字API》,所有代码参照本书的程序,加上个人的分析,肯定有不对的地方,欢迎留言指出,谢谢。

本篇介绍书中第一个代码intro/daytimetcpcli.c。这是一个客户程序,该客户与其服务器建立一个TCP连接后,服务器以直观可读格式简单地送回当前时间和日期。

以下是稍微修改过的源码:(逃

#include "../unp.h"

int main(int argc, char **argv)
{
    int sockfd, n;
    char recvline[MAXLINE + 1];
    struct sockaddr_in servaddr;

    if(argc != 2)
    {
        printf("usage: a.out <IPaddress>");
    }

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        printf("socket error");
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(13);

    if(inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
    {
        printf("inet_pton error for %s", argv[1]);
    }
    if(connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) < 0)
    {
        printf("connect error");
    }

    while((n = read(sockfd, recvline, MAXLINE)) > 0)
    {
        recvline[n] = 0;
        if(fputs(recvline, stdout) == EOF)
        {
            printf("fputs error");
        }
    }
    if(n < 0)
    {
        printf("read error");
    }
    exit(0);
}

1.程序所用的头文件皆在unp.h中包含。


2. MAXLINE是在unp.h中定义的宏,为4096。


3.结构sockaddr_in在netinet/in.h中定义。此数据结构用做bind、connect、recvfrom、sendto等函数的参数,指明地址信息。以下是其定义:

//netinet/in.h
struct sockaddr_in
{ 
    short sin_family;/*Address family一般来说AF_INET(地址族)PF_INET(协议族)*/ 
    unsigned short sin_port;/*Port number(必须要采用网络数据格式,普通数字可以用htons()函数转换成网络数据格式的数字)*/
    struct in_addr sin_addr;/*IP address in network byte order(Internet address)*/
    unsigned char sin_zero[8];/*Same size as struct sockaddr没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐*/
};
sin_family指代协议族,在socket编程中只能是AF_INET
sin_port存储端口号(使用网络字节顺序),在linux下,端口号的范围0~65535,同时0~1024范围的端口号已经被系统使用或保留。
sin_addr存储IP地址,使用in_addr这个数据结构
sin_zero是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。


4.已将err_quit、err_sys函数用printf替换,功能一样但是有可能不能正常将数据显示在终端。


5. bzero函数由名字可知,要将位置零,实际上是将一段内存的内容全清为零。代码中是对servaddr进行初始化。


6.inet_pton函数将“点分十进制” -> “二进制整数”
函数原型:int inet_pton(int af, const char *src, void *dst);
这个函数转换字符串到网络地址,第一个参数af是地址簇,第二个参数*src是来源地址,第三个参数* dst接收转换后的数据。如果函数出错将返回一个负值,并将errno设置为EAFNOSUPPORT,如果参数af指定的地址族和src格式不对,函数将返回0。

在unp.h中有如下代码:

#ifndef	HAVE_INET_PTON_PROTO
int			 inet_pton(int, const char *, void *);
const char	*inet_ntop(int, const void *, char *, size_t);
#endif


7.connect函数建立socket连线,头文件是sys/types.h和sys/socket.h。

函数原型:int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);

connect函数用来将参数sockfd的socket连接至参数serv_addr指定的网络地址。

成功返回0,失败为-1,错误原因存于errno中。


8.read函数C语言的I/O操作函数在代码中的功能是从socked中读最长为MAXLINE个位的数据放置到缓冲区recvline中。

9.fputs函数将缓冲区recvline中的数据送入标准输出文件中。


以上就是分析内容,完。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值