这一小节介绍网络编程。首先我们介绍一下计算机网络的基本知识,然后着重介绍一下Windows Socket程序的编写。
首先,介绍几个基本概念。什么是计算机网络?它是相互连接的独立自主的计算机的集合。它们是如何通信的呢,需要一个东西来表明我要跟哪个计算机进行通信,在网络上,为每个计算机分配了一个“IP”地址,通过地址来找到想要通信的计算机。具体的通信是计算机的某个程序实现的,一台计算机可能同时有多个程序在使用网络。为了区分它们,为每个程序提供了一个“端口号”来标识自己。具体通信时所发送的内容,成为协议,它规定了我们发送的格式:除了发送的内容以外,还包括这些东西是谁发送的,要发给谁,总共有多长等等。而信息具体是如何从一台主机,发送到另一台主机,则会有很大的不确定性:
不同的通信媒介:是通过有线传输的,还是无线网络?
不同的操作系统:Unix、Windows
不同的应用环境:移动、固定
不同的业务类型:对时延的要求、对差错控制的要求。
等等,使得实际中的相互通信的网络异常复杂,如何解决这个问题呢?国际标准化组织(ISO)提出了OSI(Open System Interconnected)七层参考模型,将网络按照不同的功能划分为7层:
应用层
表示层
会话层
传输层
网络层
物理层:提供二进制传输,确定在通信信道上如何传输比特流。一条物理信道上所能传送的信息的最快速度是有限制的,不是我们想传送多块就能传送多快的。为了对抗复杂的传输环境(这一点在无线通信中尤其明显),物理层通常要使用非常复杂的调制、编码技术,来在在一定差错容忍度的前提下,尽可能的多发送。
数据链路层:提供介质访问,增强物理层的传输功能,建立一条无差错的传输线路。比如对于收到物理层发送过来的数据,需要通过确认请求或者简单的差错控制编码(比如奇偶效验)来判断这一帧数据是否有错误,如果错误了,则通知发送发重新发送。
网络层:IP寻址和路由。因为网络上的数据可以经由多条路线到达目的地,所以其中要考虑路由算法、拥塞控制等问题。
传输层:为源端主机到目的端主机提供可靠的数据传输服务,隔离网络的上下层协议,是得网络应用于下层协议无关。也就是应用程序与应用程序之间的连接。
会话层:两个相互通信的应用进程之间建立、组织和协调其相互之间的通信。比如电影里使用对讲机时,一句话说完后总要加一句“over”。
表示层:被传送的数据如何表示。
应用层:用户所提供的服务。
要注意,这7层模型是功能上的划分,并不是具体一定要有这七层。
下面介绍一下应用层、传输层和网络层的常见协议(这是笔试题中常考的):
应用层协议:远程登录协议(Telnet)、文件传输协议(FTP)、超文本传输协议(HTTP)、域名服务(DNS)、简单哟见传输协议(SMTP)、邮局协议(POP3)等。
传输层:传输控制协议(TCP)、用户数据报协议(UDP)。
这两个协议值得仔细说说。
TCP协议是面向连接的,也就是说,在双方通信之前,已经安排好了一条通信线路(不管它具体是什么)共他俩使用,别人不能使用,等他俩通信结束后,需要释放这条线路。TCP是通过3次握手建立的:
1.客户端给服务器发送SYN(syn = j)包,进入SYN_SEND状态。
2.服务器接收到SYN包,确认客户的SYN(ack = j+1),同时自己也发送一个SYN包(syn = k),把它俩都发送出去,服务器进入SYN_RECV状态。
3.客户端收到服务器的SYN+ACK包,向服务器发送ACK(ack = k+1)。客户端和服务器都进入ESTABLISHED状态。此时,连接已经建立完毕,可以发送消息了。
上面只是正常的建立连接过程,其中的任何一步都有可能失败,至于失败以后的操作,这里就不细说了。
下面再看看UDP协议:这是一种无连接的、不可靠的协议。这意味着可能向对方发送的消息时对方无法接到。或者,向一个根本不存在的IP地址或者端口发送消息。既然是不可靠的,为什么还要使用它呢?因为UDP协议不需要建立连接,没有数据重传,所以实时性较高。比如我们看视频时,一两个像素的错误我们根本不会发觉。
网络层:网际协议(IP),Internet互联网报文控制协议(ICMP)、Internet组管理协议IGMP。
传输层
网络层
在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户机、服务器模式:客户向服务器发送请求,服务器收到请求后,提供相应的服务。为什么这么设计呢?首先,建立网络的原因是因为网络中软硬件资源、运算能力和信息分布不均,需要共享,从而拥有资源多的主机提供服务,资源少的客户请求服务。其次,网间进程通信完全是异步的,相互通信的进程间即不存在父子关系,又不存在共享的内存缓冲区,需要一种机制为希望通信的进程间建立联系,为二者的数据交换提供同步。
它们的通信过程如下:
服务器先运行:
1.打开一个通信通道并告知本地主机,他愿意在某一地址和端口上接收客户的请求。
2.等待客户请求到达端口。
3.接收到重复服务请求没处理该请求并发送应答信号。收到并发服务的请求,要激活一个新的进程或者线程来处理这个客户请求。新的进程或者线程处理此客户的请求,并不需要对其他请求作出相应。等服务完成后,关闭新进程与客户的通信链路,并终止。
4.返回第二步,等待另一请求。
5.关闭服务器。
客户端:
1.打开一个通信通道并连接到服务器所在的主机的特定端口。
2.向服务器发送服务请求报文,等待接收应答,继续提出请求。
3.请求结束后关闭通信通道并终止。
讲了这么多,我们可以隐约感觉到,网络编程是一件很麻烦的事情,为了方便的开发应用软件程序,美国伯克利大学在UNIX上推出了一种应用程序访问通信协议的操作系统套接字(socket),是得程序员可以很方便的访问TCP/IP协议,从而开发各种网络应用程序。后来,socket又引入到windows操作系统。我们先介绍与之相关的函数,然后给出几个例子:
1.使用WSAStartup进行版本协商。
int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);
首先,介绍几个基本概念。什么是计算机网络?它是相互连接的独立自主的计算机的集合。它们是如何通信的呢,需要一个东西来表明我要跟哪个计算机进行通信,在网络上,为每个计算机分配了一个“IP”地址,通过地址来找到想要通信的计算机。具体的通信是计算机的某个程序实现的,一台计算机可能同时有多个程序在使用网络。为了区分它们,为每个程序提供了一个“端口号”来标识自己。具体通信时所发送的内容,成为协议,它规定了我们发送的格式:除了发送的内容以外,还包括这些东西是谁发送的,要发给谁,总共有多长等等。而信息具体是如何从一台主机,发送到另一台主机,则会有很大的不确定性:
不同的通信媒介:是通过有线传输的,还是无线网络?
不同的操作系统:Unix、Windows
不同的应用环境:移动、固定
不同的业务类型:对时延的要求、对差错控制的要求。
等等,使得实际中的相互通信的网络异常复杂,如何解决这个问题呢?国际标准化组织(ISO)提出了OSI(Open System Interconnected)七层参考模型,将网络按照不同的功能划分为7层:
应用层
表示层
会话层
传输层
网络层
数据链路层
物理层
物理层:提供二进制传输,确定在通信信道上如何传输比特流。一条物理信道上所能传送的信息的最快速度是有限制的,不是我们想传送多块就能传送多快的。为了对抗复杂的传输环境(这一点在无线通信中尤其明显),物理层通常要使用非常复杂的调制、编码技术,来在在一定差错容忍度的前提下,尽可能的多发送。
数据链路层:提供介质访问,增强物理层的传输功能,建立一条无差错的传输线路。比如对于收到物理层发送过来的数据,需要通过确认请求或者简单的差错控制编码(比如奇偶效验)来判断这一帧数据是否有错误,如果错误了,则通知发送发重新发送。
网络层:IP寻址和路由。因为网络上的数据可以经由多条路线到达目的地,所以其中要考虑路由算法、拥塞控制等问题。
传输层:为源端主机到目的端主机提供可靠的数据传输服务,隔离网络的上下层协议,是得网络应用于下层协议无关。也就是应用程序与应用程序之间的连接。
会话层:两个相互通信的应用进程之间建立、组织和协调其相互之间的通信。比如电影里使用对讲机时,一句话说完后总要加一句“over”。
表示层:被传送的数据如何表示。
应用层:用户所提供的服务。
要注意,这7层模型是功能上的划分,并不是具体一定要有这七层。
下面介绍一下应用层、传输层和网络层的常见协议(这是笔试题中常考的):
应用层协议:远程登录协议(Telnet)、文件传输协议(FTP)、超文本传输协议(HTTP)、域名服务(DNS)、简单哟见传输协议(SMTP)、邮局协议(POP3)等。
传输层:传输控制协议(TCP)、用户数据报协议(UDP)。
这两个协议值得仔细说说。
TCP协议是面向连接的,也就是说,在双方通信之前,已经安排好了一条通信线路(不管它具体是什么)共他俩使用,别人不能使用,等他俩通信结束后,需要释放这条线路。TCP是通过3次握手建立的:
1.客户端给服务器发送SYN(syn = j)包,进入SYN_SEND状态。
2.服务器接收到SYN包,确认客户的SYN(ack = j+1),同时自己也发送一个SYN包(syn = k),把它俩都发送出去,服务器进入SYN_RECV状态。
3.客户端收到服务器的SYN+ACK包,向服务器发送ACK(ack = k+1)。客户端和服务器都进入ESTABLISHED状态。此时,连接已经建立完毕,可以发送消息了。
上面只是正常的建立连接过程,其中的任何一步都有可能失败,至于失败以后的操作,这里就不细说了。
下面再看看UDP协议:这是一种无连接的、不可靠的协议。这意味着可能向对方发送的消息时对方无法接到。或者,向一个根本不存在的IP地址或者端口发送消息。既然是不可靠的,为什么还要使用它呢?因为UDP协议不需要建立连接,没有数据重传,所以实时性较高。比如我们看视频时,一两个像素的错误我们根本不会发觉。
网络层:网际协议(IP),Internet互联网报文控制协议(ICMP)、Internet组管理协议IGMP。
由于7层模型在使用起来很不方便,实际中应用更广泛的是TCP/IP模型:
传输层
网络层
网络接口层
在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户机、服务器模式:客户向服务器发送请求,服务器收到请求后,提供相应的服务。为什么这么设计呢?首先,建立网络的原因是因为网络中软硬件资源、运算能力和信息分布不均,需要共享,从而拥有资源多的主机提供服务,资源少的客户请求服务。其次,网间进程通信完全是异步的,相互通信的进程间即不存在父子关系,又不存在共享的内存缓冲区,需要一种机制为希望通信的进程间建立联系,为二者的数据交换提供同步。
它们的通信过程如下:
服务器先运行:
1.打开一个通信通道并告知本地主机,他愿意在某一地址和端口上接收客户的请求。
2.等待客户请求到达端口。
3.接收到重复服务请求没处理该请求并发送应答信号。收到并发服务的请求,要激活一个新的进程或者线程来处理这个客户请求。新的进程或者线程处理此客户的请求,并不需要对其他请求作出相应。等服务完成后,关闭新进程与客户的通信链路,并终止。
4.返回第二步,等待另一请求。
5.关闭服务器。
客户端:
1.打开一个通信通道并连接到服务器所在的主机的特定端口。
2.向服务器发送服务请求报文,等待接收应答,继续提出请求。
3.请求结束后关闭通信通道并终止。
讲了这么多,我们可以隐约感觉到,网络编程是一件很麻烦的事情,为了方便的开发应用软件程序,美国伯克利大学在UNIX上推出了一种应用程序访问通信协议的操作系统套接字(socket),是得程序员可以很方便的访问TCP/IP协议,从而开发各种网络应用程序。后来,socket又引入到windows操作系统。我们先介绍与之相关的函数,然后给出几个例子:
1.使用WSAStartup进行版本协商。
int WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);