




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
计算机网络编程(基于VC++)第一篇一、TCP/IP体系结构与特点
1、TCP/IP体系结构
TCP/IP协议实际上就是在物理网上的一组完整的网络协议。其中TCP是提供传输层服务,而IP则是提供网络层服务。TCP/IP包括以下协议:(结构如图1.1)
(图1.1)
IP:网间协议(InternetProtocol)负责主机间数据的路由和网络上数据的存储。同时为ICMP,TCP,UDP提供分组发送服务。用户进程通常不需要涉及这一层。
ARP:地址解析协议(AddressResolutionProtocol)
此协议将网络地址映射到硬件地址。
RARP:反向地址解析协议(ReverseAddressResolutionProtocol)
此协议将硬件地址映射到网络地址
ICMP:网间报文控制协议(InternetControlMessageProtocol)
此协议处理信关和主机的差错和传送控制。
TCP:传送控制协议(TransmissionControlProtocol)
这是一种提供给用户进程的可靠的全双工字节流面向连接的协议。它要为用户进程提供虚电路服务,并为数据可靠传输建立检查。(注:大多数网络用户程序使用TCP)
UDP:用户数据报协议(UserDatagramProtocol)
这是提供给用户进程的无连接协议,用于传送数据而不执行正确性检查。
FTP:文件传输协议(FileTransferProtocol)
允许用户以文件操作的方式(文件的增、删、改、查、传送等)与另一主机相互通信。
SMTP:简单邮件传送协议(SimpleMailTransferProtocol)
SMTP协议为系统之间传送电子邮件。
TELNET:终端协议(TelnetTerminalProcotol)
允许用户以虚终端方式访问远程主机
HTTP:超文本传输协议(HypertextTransferProcotol)
TFTP:简单文件传输协议(TrivialFileTransferProtocol)
2、TCP/IP特点
TCP/IP协议的核心部分是传输层协议(TCP、UDP),网络层协议(IP)和物理接口层,这三层通常是在操作系统内核中实现。因此用户一般不涉及。编程时,编程界面有两种形式:一、是由内核直接提供的系统调用;二、使用以库函数方式提供的各种函数。前者为核内实现,后者为核外实现。用户服务要通过核外的应用程序才能实现,所以要使用套接字(socket)来实现。
图1.2TCP/IP协议核心与应用程序关系
二、专用术语
1、套接字
它是网络的基本构件。它是可以被命名和寻址的通信端点。套接字存在通信区域(通信区域又称地址簇)中。套接字只与同一区域中的套接字交换数据(跨区域时,需要执行某和转换进程才能实现)。WINDOWS中的套接字只支持一个域——网际域。套接字具有类型。WINDOWSSOCKET版本支持两种套接字:流套接字(SOCK_STREAM)和数据报套接字(SOCK_DGRAM)2、WINDOWSSOCKETS实现
一个WINDOWSSOCKETS实现是指实现了WINDOWSSOCKETS规范所描述的全部功能的一套软件。一般通过DLL文件来实现3、阻塞处理例程阻塞处理例程(blockinghook,阻塞钩子)是WINDOWSSOCKETS实现为了支持阻塞套接字函数调用而提供的一种机制。4、多址广播(multicast,多点传送或组播)
是一种一对多的传输方式,传输发起者通过一次传输就将信息传送到一组接收者,与单点传送(unicast)和广播(Broadcast)相对应。第二篇网络通信模型一、客户机/服务器模式在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Servermodel)。该模式的建立基于以下两点:1、非对等作用;2、通信完全是异步的。客户机/服务器模式在操作过程中采取的是主动请示方式:
首先服务器方要先启动,并根据请示提供相应服务:(过程如下)
1、打开一通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求;
2、等待客户请求到达该端口;
3、接收到重复服务请求,处理该请求并发送应答信号;
4、返回第二步,等待另一客户请求;
5、关闭服务器。
客户方:
1、打开一通信通道,并连接到服务器所在主机的特定端口。
2、向服务器发送服务请求报文,等待并接收应答;继续提出请求……
3、请求结束后关闭通信通道并终止。
二、实现网络通信的基本函数
为了更好说明套接字编程原理,给出几个基本的套接字,在以后的篇幅中会给出更详细的使用说明。
1、创建套接字—socket()
功能:创建一个新的套接字
格式:SOCKETsocket(intaf,inttype,intprocotol);
参数:af:通信发生的区域
type:要建立的套接字类型
procotol:使用的特定协议
2、指定本地地址—bind()
功能:将套接字地址与所创建的套接字号联系起来。
格式:intbind(SOCKETs,conststructsockaddr*name,intnamelen);
参数:s:是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。
其它:没有错误,bind()返回0,否则SOCKET_ERROR。
地址结构说明:
structsockaddr_in
{
shortsin_family;//AF_INET
u_shortsin_port;//16位端口号,网络字节顺序
structin_addrsin_addr;//32位IP地址,网络字节顺序
charsin_zero[8];//保留
}
3、建立套接字连接——connect()和accept()
功能:共同完成连接工作
格式:intconnect(SOCKETs,conststructsockaddr*name,intnamelen);//参数name是目标主机的地址
SOCKETaccept(SOCKETs,structsockaddr*name,int*addrlen);
//参数name代表是客户端的地址信息
4、监听连接——listen()
功能:用于面向连接服务器,表明它愿意接收连接。
格式:intFARlisten(SOCKETs,intbacklog);
5、数据传输——send()与recv()
功能:数据的发送与接收
格式:intsend(SOCKETs,constchar*buf,intlen,intflags);
intrecv(SOCKETs,constchar*buf,intlen,intflags);
参数:buf:指向存有传输数据的缓冲区的指针。6、多路复用——select()
功能:用来检测一个或多个套接字状态。
格式:intPASCALFARselect(intnfds,fd_set*readfds,fd_set*writefds,
fd_set*exceptfds,conststructtimeval*timeout);
参数:readfds:指向要做读检测的指针
writefds:指向要做写检测的指针
exceptfds:指向要检测是否出错的指针
timeout:最大等待时间7、关闭套接字——closesocket()
功能:关闭套接字s
格式:BOOLPASCALFARclosesocket(SOCKETs);三、典型通信过程图
3.1面向连接的套接字的系统调用时序图
3.2无连接协议的套接字调用时序图
//注:非连接通信收发数据的函数分别为sendto()和recvfrom()
3.3面向连接的应用程序流程图
四、具体实例客户端通信典型代码:voidCtsclientDlg::OnBnClickedOk()
{//TODO:在此添加控件通知处理程序代码
WORDwVersionRequested;
WSADATAwsaData;
interr;
intnScokErr;
wVersionRequested=MAKEWORD(1,1);
//生成版本号1.1
err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0)
{
MessageBox("找不到合适的Dll文件","错误",MB_OK);
return;
}
SOCKETsClientSock;
sockaddr_inaddr;
intnSockErr;
//创建套接字
sClientSock=socket(AF_INET,SOCK_STREAM,0);
sockaddr_inServAddr;
ServAddr.sin_family=AF_INET;
ServAddr.sin_port=htons(6000);
ServAddr.sin_addr.s_addr=inet_addr("52");
//连接到服务器
if(connect(sClientSock,(structsockaddr*)&ServAddr,sizeof(ServAddr))==SOCKET_ERROR)
{
nScokErr=WSAGetLastError();
MessageBox("连接错误!","错误",MB_OK);
}
MessageBox("连接成功!","成功",MB_OK);
Sleep(3000);
charFAR*buf;
buf="1234567890123456";
send(sClientSock,buf,16,0);
closesocket(sClientSock);
OnOK();
}服务器端源码WORDwVersion=MAKEWORD(2,0);
WSADATAwsData;
intnResult=WSAStartup(wVersion,&wsData);
if(nResult!=0)
{
MessageBox("版本不对","ok",MB_OK);
return;
}
SOCKETsock=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(sock==INVALID_SOCKET)
{
MessageBox("sockererr","err",MB_OK);
return;
}
sockaddr_inaddr;
addr.sin_family=AF_INET;
addr.sin_port=htons(6000);//保证字节顺序
addr.sin_addr.s_addr=inet_addr("52");
nResult=bind(sock,(sockaddr*)&addr,sizeof(sockaddr));
if(nResult==SOCKET_ERROR)
{
MessageBox("绑定套接字时出错","错误",MB_OK);
return;
}
nResult=listen(sock,5);//最多5个连接
if(nResult==SOCKET_ERROR)
{
MessageBox("listenerr","错误",MB_OK);
return;
}
intlen;
sockaddr_inaddrclient;
SOCKETs_d=accept(sock,(sockaddr*)&addrclient,&(len=sizeof(sockaddr)));
if(s_d==INVALID_SOCKET)
{
MessageBox("accepterr","错误",MB_OK);
return;
}
charmess[1000];
nResult=recv(s_d,mess,1000,0);
if(nResult==SOCKET_ERROR)
{
intt=WSAGetLastError();
MessageBox("rexverr","错误",MB_OK);
return;
}
MessageBox("rexvok","ok",MB_OK);一、简单的TCP服务器·首先,使用VC++应用程序向导来创建一个Win32consoleapplication。
·选择addsupportforMFC选项。
·打开stdafx.h文件,并添加这一行:#include<winsock2.h>。
·选择Project-Settings-Link,并在库模块列表中加入ws2_32.lib。main函数int_tmain(intargc,TCHAR*argv[],TCHAR*envp[])
{
intnRetCode=0;
cout<<"PressESCAPEtoterminateprogram\r\n";
AfxBeginThread(ServerThread,0);
while(_getch()!=27);
returnnRetCode;
}在main()中所做的是开启一个线程,然后对一个_getch()调用进行循环。_getch()仅仅是等待一个键的按下,并返回这个读入字符的ASCII值。我们一直循环,直到返回27这个值为止——既然27是ESCAPE键的ASCII码。你可能想知道的是,即使我们按下了ESCAPE,我们开启的线程也还会是活动的状态。不用为这些事情担心,因为当main()返回的时候,进程就会被终止,主线程开启的线程也会被突然终止。ServerThread函数现在所要做的事情就是把ServerThread函数列出来。UINT
ServerThread(LPVOIDpParam)
{
cout<<"StartingupTCPserver\r\n";
//SOCKET其实是unsignedint的一个typedef。
//在Unix中,套接字句柄就像文件句柄一样,都是unsignedint。
//既然在Windows下这些不是真的,那么我们就定义了一种新的数据类型,名为SOCKET。
SOCKETserver;
//WSADATA是一个struct,WSAStartup的调用将会填充之。
WSADATAwsaData;
//sockaddr_in为TCP/IP套接字指定了套接字的地址。
//其它的协议都使用相似的结构。
sockaddr_inlocal;
//WSAStartup为程序调用WinSock进行了初始化。
//第一个参数指定了程序允许使用的WinSock规范的最高版本。
intwsaret=WSAStartup(0x101,&wsaData);
//如果成功,WSAStartup返回零。
//如果失败,我们就退出。
if(wsaret!=0)
{
return0;
}
//现在我们来为sockaddr_in结构赋值。
local.sin_family=AF_INET;//地址族
local.sin_addr.s_addr=INADDR_ANY;//网际IP地址
local.sin_port=htons((u_short)20248);//使用的端口
//由socket函数创建我们的SOCKET。
server=socket(AF_INET,SOCK_STREAM,0);
//如果socket()函数失败,我们就退出。
if(server==INVALID_SOCKET)
{
return0;
}
//bind将我们刚创建的套接字和sockaddr_in结构联系起来。
//它主要使用本地地址及一个特定的端口来连接套接字。
//如果它返回非零值,就表示出现错误。
if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
{
return0;
}
//listen命令套接字监听来自客户端的连接。
//第二个参数是最大连接数。
if(listen(server,10)!=0)
{
return0;
}
//我们需要一些变量来保存客户端的套接字,因此我们在此声明之。
SOCKETclient;
sockaddr_infrom;
intfromlen=sizeof(from);
while(true)//无限循环
{
chartemp[512];
//accept()将会接收即将到来的客户端连接。
client=accept(server,
(structsockaddr*)&from,&fromlen);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 瀝青材料供货协议
- 短信营销合同范本
- 建设工程合同审核协议
- 送一你张年前的火车票快上车课件
- 铁路班组管理S班组执行力训练课件
- 铁路工程安全技术石家庄铁路24课件
- 现浇人行梯道施工方案
- 铁路客运站售票岗位作业李秀聪37课件
- 《GB 9132-1988低中水平放射性固体废物的浅地层处置规定》(2025版)深度解析
- 中专美术中国画课件
- 河南省洛阳市强基联盟2024-2025学年高二下学期3月月考历史试题(原卷版+解析版)
- 2025届上海市奉贤区高三语文二模试卷作文题目解析及范文:达克效应
- GB 15578-2008电阻焊机的安全要求
- 基坑支护监理质量评估报告
- 楼板裂缝鉴定报告(范本)
- PANTONE潘通色卡C卡
- 特殊过程及关键工序界定(共32页)
- V带轮设计说明书
- 电路图与实物图互画练习一二
- 京九铁路线南昌段隧道整治施工组织设计
- 拼音表(声母、带声调的韵母和整体认读音节)
评论
0/150
提交评论