网络编程之Introduction and TCP/IP(一)
2018-02-22 21:47
387 查看
写在最前
APUE篇笔者的记录十分详细,但是UNP篇就不能如此了。因为很费时间,在UNP篇的记录将保留更多的英文原文,很多地方只是总括性的总结。1. 基本概念
如果是Client发起请求,则该编程方式不会太复杂,但是有时候也有
Server发起请求到
Client,这种属于异步回调通信。从
Server的角度来看,一个
Server同时和多个
Client通信是很正常的事情。
Web Server和
Client的通信,使用
TCP或者
UDP协议,然后
TCP协议使用
IP协议,
IP协议再和数据链路层进行通信。具体的形式如下图:
Note that the actual flow of information between the client and server goes down the protocol stack on one side, across the network, and up the protocol stack on the other side.
有时候
Client和
Server在不同的局域网,然后这些局域网通过路由器连接到
WAN。此时如下图所示:
Routers are the building blocks of WANs. The largest WAN today is the Internet.
2. A Simple Daytime Client
#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); /* daytime server */ 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 = 0; /* null terminate */ if (fputs(recvline, stdout) == EOF) err_sys("fputs error"); } if (n < 0) err_sys("read error"); exit(0); }
以上程序特别强调一下几方面:
过
socket函数创建一个套签字,这点在APUE17章中已经有所涉及。
使用
server的IP地址和
daytime对应端口号填充
sockaddr_in结构体,设置地址种类为
AF_INET,特别的调用了
htons转换一个二进制端口号为合适的格式,
inet_pton转化字符串IP地址为合适的格式,并将转换后的值填充
sockaddr_in结构体的
sin_addr成员。
connect函数当用于TCP套签字时,将和
servaddr指示的主机建立一个TCP连接。
NOTE :Everytime one of the socket functions requires a pointer to a socket address structure, that pointer must be cast to a pointer to a generic socket address structure.
TCP是一种字节流协议,其并没有明显的界线,所以如果使用一次
read,并不能保证读取所有对方发送的数据,解决方式就是使用循环,当
read返回0或者负数时,终止循环。
3. A Simple Daytime Server
#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); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; 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 ( ; ; ) { connfd = Accept(listenfd, (SA *) NULL, NULL); ticks = time(NULL); snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); Write(connfd, buff, strlen(buff)); Close(connfd); } }
对于
Server程序需要强调一下几点:
通过
bind函数
daytime的端口号和本机的接口地址被绑定到前面生产的套签字上。
通过调用
listen监听
bind之后的套签字,来获取来自client的请求。如果多个请求同时到达,由内核将这些请求放入队列中,等待处理。
当调用
accpet时,该进程会被阻塞从而睡眠,等待来自
client的请求,当一个
TCP通信通过三次握手建立连接时,
accpet函数返回一个新的套签字,该套嵌字已经和
client建立连接。
当
client调用
close时,server结束该连接,这里涉及更具体的操作:
This initiates the normal TCP connection termination sequence: a FIN is sent in each direction and each FIN is acknowledged by the other end.
以上代码所展示的server属于
iterative server,还有一种
concurrent server,可以同时和多个client的连接通信,
Nginx属于这种,最简单的实现方式就是为每个请求连接的client产生一个子进程,当然也可以用多线程来完成。
4. OSI Model
We consider the bottom two layers of the OSI model as the device driver and networking hardware that are supplied with the system.
The network layer is handled by the IPv4 and IPv6 protocols.The transport layers that we can choose from are TCP and UDP.
We show a gap between TCP and UDP indicate that it is possible for an application to bypass the transport layer and use IPv4 or IPv6 directly. This is called a raw socket, The upper three layers of the OSI model are combined into a single layer called the application.
First, the upper three layers handle all the details of the application (FTP, Telnet, or HTTP, for example) and know little about the communication details. The lower four layers know little about the application, but handle all the communication details: sending data, waiting for acknowledgments, sequencing data that arrives out of order, calculating and verifying checksums, and so on.
The second reason is that the upper three layers often form what is called a user process while the lower four layers are normally provided as part of the operating system (OS) kernel.
5. Discovering Network Topology
两个实用工具:netstat和
ifconfig.
netstat -i provides information on the interfaces. We also specify the -n flag to pri
b3fc
nt numeric addresses, instead of trying to find names for the networks. This shows us the interfaces and their names.
netstat -r shows the routing table, which is another way to determine the interfaces. We normally specify the -n flag to print numeric addresses. This also shows the IP address of the default router.
使用
ifconfig可以查询接口的详细信息:
This shows the IP address, subnet mask, and broadcast address. The MULTICAST flag is often an indication that the host supports multicasting. Some implementations provide a -a flag, which prints information on all configured interfaces.
相关文章推荐
- 赵雅智_java网络编程(4)TCP/IP、Http和Socket的区别
- 聊聊Socket、TCP/IP、HTTP、FTP及网络编程
- TCP/IP网络编程四书五经
- android 网络编程--socket tcp/ip udp http之间的关系
- TCP/IP 网络编程 (三)
- 第23天 网络编程、udp、tcp,ip
- 聊聊Socket、TCP/IP、HTTP、FTP及网络编程
- Windows Socket 网络编程 TCP/IP体系结构、特点及相关术语
- 关于Socket、TCP/IP、HTTP、FTP及网络编程
- tcp/ip 网络编程 socket
- java网络编程自学(三)-TCP/IP+NIO
- (转)iOS 各种网络编程总结--进程、线程、Socket、HTTP、TCP/IP、TCP和UDP
- linux网络编程之IP协议首部格式与其配套使用的四个协议(ARP,RARP,ICMP,IGMP)和TCP、UDP协议头结构总结
- 菜鸟学习历程【22】网络编程、TCP/IP、TCP与UDP
- android开发第四弹--网络编程之socket tcp/ip udp http(一)
- Linux下高性能网络编程中的几个TCP/IP选项_SO_REUSEADDR、SO_RECVBUF、SO_SNDBUF、SO_KEEPALIVE、SO_LINGER、TCP_CORK、TCP_NODE
- 孙鑫VC学习(第14课网络编程,TCP/IP,UDP)
- iOS 各种网络编程总结--进程、线程、Socket、HTTP、TCP/IP、TCP和UDP
- linux网络编程之套接字/TCP/IP
- WINDOWS (服务器) 和 DOS(客户端) 网络互连 基于TCP/IP的编程实现