1、OSI各层的主要功能:物理层:通常规定网络传输媒体的机械、电气、功能、规程等特性,用来实现数据链路实体间透明的比特(Bit)流传输。数据链路层:提供链路管理、帧同步、差错控制、流量控制、寻址等功能,主要用途是为在相邻网络实体之间建立、维持和释放数据链路连接,并传输数据链路服务数据单元。网络层:提供路由选择、流量控制等功能,实现源DCE(DataCommunicationEquipment)和目标DCE之间的通信建立、维护和终止网络连接,并通过网络连接交换网络服务数据单元。运输层:主要完成从会话层接收数据,并且把它分成较小的单元,传输给网络层,在优化网络服务的基础上,为源主机和目标主机之间提供可靠的价格、合理的透明传输,使其上面的高层不必关心通信子网的实现细节。会话层:管理和终止两个通信主机之间的会话。表示层:确保一个系统的应用层发送的信息能被另一个系统的应用层读取。应用层:提供给人们解决具体问题的功能,是用户使用OSI功能的惟一窗口。2、TCP/IP各层的主要功能:网络接口层:主机至网络层:代表了传输能力以及接口的使用。网络层:使主机可以把分组发往任何网络并且使分组独立地传向目标。传输层:主要实现两个不同的协议无连接的UDP和面向联接的TCP。应用层:提供解决具体应用问题的功能。TCP特点:面向连接、点对点、可靠、全双工、面向字节流UDP特点:无连接、不可靠、无拥塞控制、面向报文、交互通信主要步骤a.服务器创建套接字SOCEKTsocket(intaf,inttype,intprotocol);b.绑定端口号intbind(SOCKETs,conststructsockaddrFAR*name,intnamelen);c.监听(UDP没有)intlisten(SOCKETs,intbacklog);d.接收连接(UDP没有)SOCKETaccept(SOCKETs,structsockaddrFAR*addr,intFAR*addrlen)e.客户进程调用socket创建客户套接字f.客户向服务器发出一个请求,建立链接,使用connect函数,函数原型如下:intconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen);h.此时,客户机的套接字已经接收到服务器的信号,接下来可以进行数据传送了,可以用send和recv函数来收发数据,函数原型如下:intsend(SOCKETs,constcharFAR*buf,intlen,intflags);intrecv(SOCKETs,charFAR*buf,intlen,intflags);intsendto(SOCKETs,char*buf,intlen,intflags,structsockaddr*to,inttolen);intrecvfrom(SOCKETs,char*buf,intlen,intflags,structsockaddr*from,int*fromlen);I:关闭连接intclosesocket(SOCKETs);TCP服务器:charsztext[]=欢迎你\r\n;s=::socket(AF_INET,SOCK_STREAM,0);sockaddr_inaddr,addr2;intn=sizeof(addr2);addr.sin_family=AF_INET;addr.sin_port=htons(10037);addr.sin_addr.S_un.S_addr=INADDR_ANY;::bind(s,(sockaddr*)&addr,sizeof(addr));::listen(s,2);chartext[1000];printf(服务器已经启动\r\n);while(true){s1=::accept(s,(sockaddr*)&addr2,&n);if(s1!=NULL){printf(%s已经连接上\r\n,inet_ntoa(addr2.sin_addr));::send(s1,sztext,sizeof(sztext),0);}::closesocket(s);::closesocket(s1);TCP客户端:charsztext[10]={0};s=::socket(AF_INET,SOCK_STREAM,0);//创建TCP套接字sockaddr_inaddr;//定义套接字地址结构addr.sin_family=AF_INET;//初始化地址结构addr.sin_port=htons(10037);addr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);printf(客户端已经启动\r\n);//输出提示信息::connect(s,(sockaddr*)&addr,sizeof(addr));::recv(s,sztext,sizeof(sztext),0);printf(%s\r\n,sztext);::closesocket(s);//关闭套接字句柄::WSACleanup();//释放套接字库UDP服务器:{//WSA启动省略charsztext[]=欢迎你\r\n;s=::socket(AF_INET,SOCK_DGRAM,0);//SOCK_DGRAM数据报套接字sockaddr_inaddr,addr2;intn=sizeof(addr2);charbuff[11]={0};addr.sin_family=AF_INET;addr.sin_port=htons(75);addr.sin_addr.S_un.S_addr=INADDR_ANY;::bind(s,(sockaddr*)&addr,sizeof(addr));printf(UDP服务器已经启动\r\n);while(1){if(::recvfrom(s,buff,11,0,(sockaddr*)&addr2,&n)!=0){printf(%s已经连接上\r\n,inet_ntoa(addr2.sin_addr));printf(%s\r\n,buff);::sendto(s,sztext,sizeof(sztext),0,(sockaddr*)&addr2,n);break;}}::closesocket(s);::WSACleanup();UDP客户端:charsztext[]=服务器,你好!\r\n;s=::socket(AF_INET,SOCK_DGRAM,0);sockaddr_inaddr,addr2;intn=sizeof(addr2);charbuff[10]={0};addr.sin_family=AF_INET;addr.sin_port=htons(75);addr.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);printf(UDP客户端已经启动\r\n);if(::sendto(s,sztext,sizeof(sztext),0,(sockaddr*)&addr,n)!=0){::recvfrom(s,buff,10,0,(sockaddr*)&addr2,&n);printf(服务器说:%s\r\n,buff);::closesocket(s);::WSACleanup();}•ARP是AddressResolutionProtocol(地址转换协议)的简称,是TCPIP协议中最底层的协议之一。它的作用是完成IP地址到MAC(物理地址)的转换。•原理:当主机A要和主机B通信(如主机APing主机B)时。主机A会先检查其ARP缓存内是否有主机B的MAC地址。如果没有,主机A会发送一个ARP请求广播包,此包内包含着其欲与之通信的主机的IP地址,也就是主机B的IP地址。当主机B收到此广播后,会将自己的MAC地址利用ARP响应包传给主机A,并更新自己的ARP缓存,也就是同时将主机A的IP地址/MAC地址对保存起来,以供后面使用。主机A在得到主机B的MAC地址后,就可以与主机B通信了。同时,主机A也将主机B的IP地址/MAC地址对保存在自己的ARP缓存内。•GetIpNetTable功能:使用IP帮助来获取和修改ARP表信息•SetIpNetEntry向ARP表添加入口•DeleteIpNetEntry删除ARP入口函数•SendARP发送一个带有目的IP地址的ARP请求去获取一个MAC地址套接字,是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。端口号的分配机制网络进程通信前必须获知对方的进程地址。由于网络应用程序大多采用C/S模式开发,通信总是由客户机发起,因此事先只需让客户机知道服务器的进程地址即可。Internet中为客户服务的众所周知的服务有限。TCP/IP协议采用了全局分配(静态分配)和本地分配(动态分配)相结合的分配方法。对于TCP或UDP,将它们的全部65535个端口号分为保留端口号和自由端口号两部分。保留端口号,范围是0-1023,又称为众所周知的端口或熟知端口(well-knownport),只占少数,采用全局分配或集中控制的方式,由一个公认的中央机构根据需要进行统一分配,静态地分配给因特网上著名的众所周知的服务器进程,并将结果公布于众。阻塞模式在阻塞模式下,程序在调用接收函数时(如recv),如果没有数据到达,此函数会一直等待,即当前线程会被阻塞,直到有数据时才返回!换句话说,没有数据到达时,程序回在这行代码上等待,不继续往下执行。有数据到达后,函数返回非阻塞模式在非阻塞模式下,程序在调用接收函数时,接收函数会立即返回,调用方还可以进行其它操作,而当有数据到达进,操作系统会通过某些方法(如事件)来通知你!换句话说,不论是否有数据到达,程序一直往下执行。而数据到达后,操作系统会通知程序,程序根据操作系统通知的信息来做相应处理在非阻塞模式下利用socket事件的消息机制,Server端与Client端之间的通信处于异步状态下。通常需要从CSocket类派生一个新类,派生新类的目的是重载socket事件的消息函数,然后在socket事件的消息函数中添入合适的代码以完成Client端与Server端之间的通信,与阻塞模式相比,非阻塞模式无需创建一个新线程。5.3CSocket类的编程模型下面给出针对流式套接字的CSocket类的编程模型。分为服务器端和客户端。1.服务器端(1)CSocketsockServ;//创建空的服务器端监听套接字对象。//用众所周知的端口,创建监听套接字对象的底层套接字句柄。(2)sockServ.Create(nPort);(3)sockServ.Listen();//启动对于客户端连接请求的监听。(4)CSocketsockRecv;//创建空的服务器端连接套接字对象。//接收客户端的连接请求,并将其他的任务转交给连接套接字对象。sockServ.Accept(sockRecv);(5)CSockFile*file;file=newCSockFile(&sockRecv);//创建文件对象并关联到连接套接字对象。(6)CArchive*arIn,arOut;arIn=CArchive(&file,CArchive::load);//创建用于输入的归档对象,arOut=CArchive(&file,CArchive::store);//创建用于输出的归档对象。//归档对象必须关联到文件对象。(7)arIndwValue;//进行数据输入。adOutdwValue;//进行数据输出。输入或输出可以反复进行。(8)sockRecv.Close();sockServ.Close();//传输完毕,关闭套接字对象。2.客户端(1)CSocketsockClient;//创建空的客户机端套接字对象。(2)sockClient.Create(