unp之datetime

一.配置unp.h
1.从www.unpbook.com下载源码
2.

1
2
3
4
5
6
tar -xzvf unpv13e.tar.gz
cd unpv13e
./configure
cp config.h /usr/include
cp libunp.a /usr/lib
cp key/unp.h /usr/include

/usr/include/unp.h中的#include "../config.h"改为#include "config.h"
3.编译如果遇到如下错误,请将unp.h中的struct in_pktinfo定义删除。
image


datetimecli.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include    "unp.h"

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

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

// 创建一个字节流套接字,并返回一个描述符
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");

bzero(&servaddr, sizeof(servaddr)); //对网络套接字结构清零
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13); // 端口号必须使用特定格式,所以需要通过htons函数进行转换

// 把ASCII命令行参数转换为合适的格式
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
err_quit("inet_pton error for %s", argv[1]);

if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");

while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
recvline[n] = 0; /* null terminate */
if (fputs(recvline, stdout) == EOF)
err_sys("fputs error");
}
if (n < 0)
err_sys("read error");

exit(0);
}
datetimesrv.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include    "unp.h"
#include <time.h>

int
main(int argc, char **argv)
{
int listenfd, connfd;
struct sockaddr_in servaddr;
char buff[MAXLINE];
time_t ticks;

listenfd = Socket(AF_INET, SOCK_STREAM, 0);// Socket是经过封装的socket函数,增加了错误处理

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
// 指定IP地址为INADDR_ANY,这样要服务器主机有多信网络接口,服务器进程就可以在任意网络接口上接受客户连接
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(13); /* daytime server */

Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

//把该套接字转换为一个监听套接字,这样来自客户的外来连接就可在该套接字上由内核接受
Listen(listenfd, LISTENQ);

for ( ; ; ) {
// 服务器进程在accept调用中被投入睡眠,等待某个客户连接的到来并被内核接受。TCP连接所使用的三路握手来建立连接。握手完毕时accept返回,其返回值是一个称为已连接描述符的新描述符。该描述符用于与新连接的那个客户通信。accept为每个连接到本服务器的客户返回一个新的描述符。
connfd = Accept(listenfd, (SA *) NULL, NULL);

ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));

// 往已连接描述符中写入数据
Write(connfd, buff, strlen(buff));

// 服务器通过调用close关闭与客户端的连接
Close(connfd);
}
}

3.测试

1
2
gcc daytimetcpcli.c -o daytimetcpcli -lunp
gcc daytimetcpsrv.c -o daytimetcpsrv -lunp

先运行daytimetcpsrv,再运行daytimetcpcli
image


Ref:
1.unix网络编程-volume1