UNP学习笔记——第一章简介

★UNP一书主要注重于 应用层 和 传输层之间的部分。

★包裹函数:大写字母开头,即封装了出错判断和处理,节省了一些代码量

★unp.h安装步骤:

1.从网络上下载unpv13e.tar文件,这里用的是自己已经修改过的,可以在CentOS上运行,不需要再为一些编译错误去修改。

       2.安装脚本,用于服务器如果挂了的话重装unp.h时方便点

tar -zxvf unpv13e.tar.gz
rm -y unpv13e.tar.gz
cd unpv13e
./configure
cd lib
make
cd ../libfree
make
cd ..
cp libunp.a /usr/lib
cp lib/unp.h /usr/include
cp config.h /usr/include
   3.生成目标程序时,记得是 gcc daytimetcpcli.c -o cli -lunp  

    ★时间获取例程(带注释)

客户端程序

#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("usge: a.out<IPaddress>");
	}
	//socket函数创建一个网际字节流套接字
	//AF_INET指网际
	//SOCK_STREAM指字节流
	//sockfd是套接字的描述符
	if ( (sockfd = socket(AF_INET,SOCK_STREAM, 0)) < 0){
		err_sys("socket error");
	}
	
	//bzero清空socket的地址结构
	//bzero是unp.h里定义的函数,用来替代memset
	bzero(&servaddr, sizeof(servaddr));
	
	//地址族置为AF_INET
	servaddr.sin_family = AF_INET;
	//设置端口号为13,是时间服务器的端口
	//htons指 主机 到 网络短整数
	servaddr.sin_port = htons(13);
	
	
	//inet_pton 把 argv[1]所传递的IP地址,转为sin_addr的数据结构
	if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){
		err_quit("inet_pton error for %s", argv[1]);
	}
	//SA就是struct sockaddr
	//将本地的sockfd套接字,与servaddr中对应的服务器进行连接
	if (connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) < 0){
		err_sys("connect error");
	}
	
	
	//读取返回的内容,并将结尾置为‘\0’
	//注意TCP本身不提供字节流末尾的结束标志,即0标志。
	//所以要自己置0
	while ( (n = read(sockfd, recvline, MAXLINE)) > 0){
		recvline[n] = 0;
		fputs(recvline, stdout);
	}
	if (n < 0){
		err_sys("read error");
	}
	exit(0);
}
              服务器例程:

#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;
	
	
	//建立一个监听套接字,并与13端口绑定Bind
	listenfd= Socket(AF_INET, SOCK_STREAM, 0);
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	//接收任意接口(非端口),故可同时接受多个接口来的请求
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
	servaddr.sin_port = htons(13);
	Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
	
	//建立监听描述符
	Listen(listenfd, LISTENQ);
	while(1){
		//进入睡眠,等待客户连接的到达并被内核接受
		//建立连接时,进行三次握手
		//accept返回已连接起来的描述符,该描述符用来与对应客户通信
		connfd = Accept(listenfd, (SA *) NULL, NULL);
	    printf("Get a request!");
		//获取自1970年以来的秒数
		ticks = time(NULL);
		
		//之所以用snprintf,而不是sprintf
		//主要是因为该函数有缓冲区的检查,而sprintf没有
		snprintf(buff, sizeof(buff), "%.24s\r\n",ctime(&ticks));
		//发送
		Write(connfd, buff, strlen(buff));
		//终止连接,等待下一次的连接
		Close(connfd);
	}
}

★常用的一些网络命令

查看服务器的网络接口信息(有哪些接口):          netstat -i              

展示路由表:netstat -r

查看对应接口的详细信息:ifconfig 接口名字

查看本地网络中其他主机的IP:  ping -b 广播地址      (因为防火墙限制可能会无法广播成功)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值