您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 商业计划书 > 孙鑫第十四课网络编程
欢迎dianxin07219880我的:收件箱资源博客空间设置|帮助|退出CSDN首页资讯论坛博客下载搜索更多oCTO俱乐部o学生大本营o培训充电o移动开发o软件研发o云计算o程序员oITeyeoTUP王定桥的专栏Maybe,Ican'tgettheansweratthemoment,butIbelieveIwillfinditfinally!目录视图摘要视图订阅精创之作《雷神的微软平台安全宝典》诚邀译者移动业界领袖会议·上海·6.20第四届云计算大会门票抢购:史上最低价,每日限5张!【分享季1】:网友推荐130个经典资源,分享再赠分!Windows程序设计__孙鑫C++Lesson14《网络编程》分类:WindowsVC++程序设计2012-02-0121:4983人阅读评论(0)收藏举报Windows程序设计__孙鑫C++Lesson14《网络编程》本节要点:1.网络协议参考模型简介2.套接字简介3.网络字节顺序4.客户机/服务器模式简介5.WindowsSockets的实现6.Windows网络编程函数准备7.基于TCP的套接字编程8.基于UDP的套接字编程//*************************************************************************************1.网络协议参考模型简介OSI七层参考模型TCP/IP的四层模型这部分内容涉及理论知识比较丰富,请参见谢希仁《计算机网络》.这里仅把帮助理解的图列在下面:2.套接字简介套接字存在于通信区域中。通信区域也叫地址族,它是一个抽象的概念,主要用于将通过套接字通信的进程的公有特性综合结合在一起。套接字通常只与同一区域的套接字交换数据(也有可能跨区域通信,但这只在执行了某种转换进程后才能实现)。WindowsSockets只支持一个通信区域:网际域(AF_INET),这个域被使用网际协议簇通信的进程使用。3.网络字节顺序不同的计算机存放多字节值得顺序不同,有的机器在起始地址存放低位字节(低位先存),有的机器在起始地址存放高位字节(高位先存)。基于Intel的cpu,即我们常用的pc机采用的是低位先存。为保证数据的正确性,在网络协议中需要使用指定的网络字节顺序。TCP/IP协议使用16位整数和32位整数的高位先存格式。4.客户机/服务器模式简介详细内容请参见谢希仁《计算机网络》.这里介绍如下图所示:5.WindowsSockets的实现(1)WindowsSockets是从伯克利套接字扩展而来,以动态链接库的形式提供给我们使用。WindowsSockets扩充主要是提供了一些异步函数,并增加了符合Windows消息驱动特性的网络事件异步选择机制。(2)套接字的类型流式套接字(SOCK_STREAM)提供面向连接、可靠的数据传输服务,数据无差错、无重复的发送,且按发送顺序接收,基于TCP协议实现的。数据报式套接字(SOCK_DGRAM)提供无连接服务。数据包以独立包形式发送,不提供无错保证,数据可能丢失或者重复,并且接收顺序混乱,基于UDP协议实现的。原始套接字(SOCK_RAM)这里不做介绍。6.Windows网络编程函数准备(1)intWSAStartup(WORDwVersionRequested,//WindowsSockets版本信息高字节指定最低版本,//低位字节表示主版本LPWSADATAlpWSAData//);该函数加载了Ws2_32.dll动态链接库,每次成功调用后应用程序必须在使用完后调用WSACleanup释放Ws2_32.dll的资源,终止其使用.(2)SOCKETsocket(intaf,//指定地址族对于TCP/IP协议的套接字inttype,//指定Socket类型intprotocol//是与特定的地址家族相关的协议指定为0那么他就会根据地址格式和套接字类别,自动为你选择一个合适的协议);创建一个和指定服务提供者绑定的套接字。(3)intbind(SOCKETs,//待绑定的套接字conststructsockaddrFAR*name,//指定了该套接字的本地地址信息指向sockaddr指针intnamelen//指定第二个参数的长度);用来绑定一个本地地址和套接字。structsockaddr{u_shortsa_family;charsa_data[14];};在TCP/IP协议中,我们可以用SOCKADDR_IN结构来替换sockaddr,以方便我们填写地址信息。structsockaddr_in{shortsin_family;u_shortsin_port;structin_addrsin_addr;charsin_zero[8];};(4)inet_addr将包含一个IPv4地址的字符串转换为IN_ADDR结构的合适的地址inet_ntoa将一个IPv4地址转换为形如a.b.c.d形式的字符串htonl将一个u_long结构的32位主机字节序的数转换为TCP/IP网络字节序htons将一个u_short结构的16位主机字节序的数转换为TCP/IP网络字节序(5)TCP发送数据intsend(SOCKETs,constcharFAR*buf,intlen,intflags);TCP接受数据intrecv(SOCKETs,charFAR*buf,intlen,intflags);(6)UDP发送数据intsendto(SOCKETs,constcharFAR*buf,intlen,intflags,conststructsockaddrFAR*to,inttolen);UDP接受数据intrecvfrom(SOCKETs,charFAR*buf,intlen,intflags,structsockaddrFAR*from,intFAR*fromlen);7.基于TCP的套接字编程注意:添加两个程序到一个工程,通过选中组建来切换工程。先启动服务器端,后启动客户端。TCP客户端和服务器端的编写过程如下图所示://实验代码如下//*************************************************************************************//TcpSrv.cpp#includeWinsock2.h#includestdio.hvoidmain(){WORDwVersionRequested;WSADATAwsaData;interr;wVersionRequested=MAKEWORD(1,1);//加载Ws2_32.dllerr=WSAStartup(wVersionRequested,&wsaData);if(err!=0){return;}if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1){WSACleanup();return;}SOCKETSocketSrv=socket(AF_INET,SOCK_STREAM,0);//step1建立套接字SOCKADDR_INAddrSrv;AddrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//网络字节序AddrSrv.sin_family=AF_INET;AddrSrv.sin_port=htons(6000);//端口号两个字节bind(SocketSrv,(SOCKADDR*)&AddrSrv,sizeof(SOCKADDR));//step2绑定到套接字listen(SocketSrv,5);//step3监听连接请求5为队列长度SOCKADDR_INAddrClient;intlen=sizeof(SOCKADDR);//必须赋初值//服务器端程序循环运行while(1){SOCKETScoketConn=accept(SocketSrv,(SOCKADDR*)&AddrClient,&len);//step4接受请求AddrClient接收连接请求方的信息charSendBuf[100];sprintf(SendBuf,Wellcome!Connectfrom%sSuccess!,inet_ntoa(AddrClient.sin_addr));send(ScoketConn,SendBuf,strlen(SendBuf)+1,0);//step5发送数据用连接的套接字不能用处于监听状态的套接字charRecvBuf[100];recv(ScoketConn,RecvBuf,100,0);//step5接收数据printf(%s\n,RecvBuf);closesocket(ScoketConn);}//实际上还需做以下操作但上述是死循环因此没有执行下述操作closesocket(SocketSrv);//关闭套接字WSACleanup();//终止库引用}//*************************************************************************************//TcpClient.cpp#includeWinsock2.h#includestdio.hvoidmain(){WORDwVersionRequested;WSADATAwsaData;interr;wVersionRequested=MAKEWORD(1,1);err=WSAStartup(wVersionRequested,&wsaData);if(err!=0){return;}if(LOBYTE(wsaData.wVersion)!=1||HIBYTE(wsaData.wVersion)!=1){WSACleanup();return;}SOCKETSocketClient=socket(AF_INET,SOCK_STREAM,0);//step1建立套接字SOCKADDR_INAddrSrv;AddrSrv.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);//本地回路地址AddrSrv.sin_family=AF_INET;AddrSrv.sin_port=htons(6000);connect(SocketClient,(SOCKADDR*)&AddrSrv,sizeof(SOCKADDR));//step2连接请求charRecvBuf[100];recv(SocketClient,RecvBuf,100,0);//接收服务器数据printf(%s\n,RecvBuf);charsendbuf[100];sprintf(sendbuf,thisisfrom%s,liming);send(SocketClient,sendbuf,strlen(sendbuf)+1,0);//发送数据closesocket(SocketClient);//关闭套接字释放资源WSACleanup();//终止套接字库的引用}//*************************************************************************************启动程序后(注意先启动服务器程序,后启动客户端程序)运行效果://*************************************************************************************8.基于UDP的套接字编程UDP服务端和客户端编写过程如下图所示://实验代码如下//*************************************************************************************//NetSrv.cpp#includeWinsock2.h
本文标题:孙鑫第十四课网络编程
链接地址:https://www.777doc.com/doc-2560403 .html