1、计算机网络基本知识

  最简单的网络程序如图:

【vc】14_网络编程_socket编程

  提示:IP地址就相当于一个公司的总机号码,端口号就相当于分机号码。在打电话时,拨通总机后,还需要转到分机上。

(1)协议

    ·为进行网络中的数据交换(通信)而建立的规则、标准或约定(=语义+语法+规则);

    ·不同层具有各自不同的协议;

(2)网路的状况

    ·多种通信媒介---有线、无线···

    ·不同种类的设备---通用、专用···

    ·不同的操作系统---UNIX、Windows···

    ·不同的应用环境---固定、移动···

    ·不同的业务种类---分时、交互、实时···

    ·宝贵的投资和积累---有形、无形···

    ·用户业务的延续性---不允许出现大的跌岩起伏;

   他们互相交织,形成了非常复杂的系统应用环境。    

(3)ISO/OSI七层参考模型

【vc】14_网络编程_socket编程

    ·物理层:提供二进制传输,确定在通信信道上如何传输比特流;

    ·数据链路层:提供介质访问,加强物理层的传输功能,建立一条无差错的传输线路;

    ·网络层:提供IP寻址和路由(网络上数据可以经由多条线路到达目的地,网络层负责找出最佳的传输线路);

    ·传输层:为源端主机到目的端主机提供可靠的数据传输服务,隔离网络的上下层协议,使得网络应用与下层协议无关;

    ·会话层:在两个相互通信的应用进程之间建立、组织和协调其相互之间的通信;

    ·表示层:处理被传送数据的表示问题,即信息的语法和语义;如有必要,可使用一种通用的数据表示格式,在多种数据表示之间进行转换。例如在日期、货币、数值等本地数据表示格式和标准数据表示格式之间进行转换,还有数据的加解密、压缩和解压缩等;

    ·应用层:为用户的网络应用程序提供网络通信的服务;

   注意:在进行一次网络通信时,每一层为本次通信提供本次的服务(通信实体的对等体之间不允许直接通信);

      各层之间是严格单向依赖;

      上层使用下层提供的服务---Service user;

      下层向上层提供服务---Service provider;

【vc】14_网络编程_socket编程

(图片引用于别处)

  应用层、传输层、网络层各使用的协议

    应用层:Telnet(远程登录协议)、FTP(文件传输协议)、HTTP(超文本传输协议)、DNS(域名服务)、SMTP(简单邮件传输协议)、POP3(邮局协议)等;

    传输层:TCP(传输控制协议)、UDP(用户数据报协议);

    网络层:网际协议IP、Internet互联网控制报文协议ICMP、Internet组管理协议IGMP;

(4)数据封装

    ·一台计算机要想另一台计算机发送数据,首先必须将该数据打包,打包的过程成为封装(即:在数据前面加上特定的协议头部);

    ·PDU(协议数据单元):对等层协议之间交换的信息单元的统称;

    ·头部含有的数据中含有王城数据传输所需的控制信息;

(5)TCP/IP模型

(6)端口

    ·传输层提供进程(活动的应用程序)通信的能力;为了标识通信实体中进行通信的进程(应用程序),TCP/IP协议提出了协议端口(protocol port,简称端口)的概念;

    ·端口用一个整数型标识符来表示,即端口号;端口号跟协议相关,TCP/IP传输层的两个协议TCP和UDP是完全独立的两个软件模块,因此各自的端口号也相互独立;

    ·我们在编写网络应用程序时,要为程序指定1024以上的端口号;1024以下端口号保留给预定义的服务;

(7)套接字的引入

    ·套接字存在于通信区域中;通信区域也叫地址族,主要用于将通过套接字通信的进程的共有特性综合在一起;

    ·套接字通常只与同一区域的套接字交换数据(也有可能跨区域通信,但这只在执行了某种转换进程后才能实现);

    ·Windows Sockets只支持一个通信区域:网际域(AF_INET),这个域被使用网际协议簇通信的进程使用;

(8)网络字节顺序

    ·不同的计算机存放多字节的顺序不同;

    ·基于Inter的CPU,采用的是低位先存。为保证数据的正确性,在网络协议中需要指定网络字节顺序,TCP/IP协议使用16位整数和32位整数的高位先存格式;

    ·网络中不同主机间进行通信时,要同一采用网络字节顺序

(9)客户机/服务器模式

【vc】14_网络编程_socket编程

图片来自:http://pic002.cnblogs.com/images/2012/387401/2012111509190090.jpg

 

   客户机/服务器在操作过程中采用主动请求的方式,首先服务器方要先启动,并根据请求提供相应的服务:

    ①打开一个通信通道并告知本地主机,他愿意在某一地址可端口上接收客户请求;

    ②等待客户请求到达该端口;

    ③接收到重复服务请求,处理请求并发送应答信息。接收到并发起服务请求,要激活一个新的进程(或线程)来处理这个客户请求。新进程(或线程)处理此客户请求,并不需要对其他请求做出应答。服务完成后,关闭此新进程与客户的通信链接,并终止;

    ④返回第二步,等待另一客户请求;

    ⑤关闭服务器;

  客户方:

    ①打开一个通信通道,并连接到服务器所在主机的特定端口;

    ②想服务器发送服务请求报文,等待并接收应答;继续提出请求;

    ③请求结束后关闭通信通道并终止;

2、Windows Sockets的实现

  Socket是连接应用程序与网络驱动程序的桥梁,Socket在应用程序中创建,通过绑定操作与驱动程序建立关系。此后,应用程序送给Socket的数据,由Socket交给驱动程序向网络上发送出去。计算机从网络上收到与该Socket绑定的IP地址和端口号相关的数据后,由驱动程序交给Socket。应用程序便可从该Socket中提取接收到的数据。

(1)套接字的类型

    ·流式套接字(SOCK_STREAM)

       提供面向连接、可靠的数据传输服务,数据乌差错、无重复的发送,且按接发送顺序接收;SOCK_STREAM是基于TCP协议实现的;

    ·数据报式套接字(SOCK_DGRAM)

       提供无连接服务;数据包以独立包形式发送,不提供无差错保证,数据可能丢失和重复,并且接收顺序混乱;SOCK_DGRAM是基于 UDP协议实现的;

    ·原始套接字(SOCK_RAW)

(2)基于TCP(面向连接)的Socket编程

  基于基于TCP(面向连接)的Socket编程的服务端程序流程如下:

    ①创建套接字(socket);

    ②将套接字绑定到一个本地地址和端口上(bind);(解释:告诉本地主机它打算在哪个IP地址和哪个端口上等待客户请求)

    ③将套接字设为监听模式,准备接收客户请求(listen);

    ④等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此连接的套接字(accept);

    ⑤用返回的套接字和客户端进行通信(send/recv);

    ⑥返回,等待另一个客户请求;

    ⑦关闭套接字;

  基于基于TCP(面向连接)的Socket编程的客户端程序流程如下:

    ①创建套接字(socket);

    ②向服务器发出连接请求(connect);

    ③和服务器端进行通信(send/recv);

    ④关闭套接字;

  在服务器端,当调用accept函数时,程序就会等待,等待客户端调用connect函数发出连接请求,然后服务器端接收该请求,于是双方就建立了连接,之后,服务器端和客户端就可以利用send和recv函数进行通信了。

(3)基于UDP(面向无连接)的socket编程

  接收端(服务器端):先启动的一端;发送端(客户端):发送数据的一端;

  接收端程序的编写:

    ①创建套接字(socket);

    ②将套接字绑定到一个本地地址和端口上(bind);(解释:接收端告诉本地主机,它是在哪个地址和端口上等待数据的到来)

    ③等待接收数据(recvfrom);

    ④关闭套接字;

  客户端程序的编写:

    ①创建套接字(socket);

    ②向服务器发送数据(sendto);

    ③关闭套接字;

提示:套接字表示了通信的端点;利用套接字通信与利用电话机通信是一样的,套接字相当于电话机,IP地址相当于总机号码,端口号相当于分机。

3、相关函数

  (1)WSAStartup函数

int WSAStartup(
  WORD wVersionRequested,  //指定准备加载的Winsock库的版本;
  LPWSADATA lpWSAData       //是一个返回值,指向WSADATA结构的指针
);
//lpWSAdata:这是一个返回值,指向WSADATA结构的指针,WSAStartup函数用其加载的库版本有关的信息填在这个结构中;

    ·功能:①加载套接字库;

        ②进行套接字库的版本的协商(确定将使用的socket版本);

    ·对于每一个WSAStartup函数的成功调用(即成功加载WinSock动态库后),在最后对应一个WASCleanUp调用,来释放该程序占用的资源,终止对WinSock动态库的使用。

typedef struct WSAData {
  WORD                  wVersion;  
  WORD                  wHighVersion;
  char                  szDescription[WSADESCRIPTION_LEN+1];
  char                  szSystemStatus[WSASYS_STATUS_LEN+1];
  unsigned short        iMaxSockets;
  unsigned short        iMaxUdpDg;
  char FAR *            lpVendorInfo;
} WSADATA, *LPWSADATA; 
View Code

相关文章: