1 / 53

网络程序设计

. TCP/IP 协议. . 协议软件接口 -socket. . 网络程序设计. Windows 网络编程 --winsock. . TCP 通信的例子程序. . UDP 通信的例子程序. . 参考书籍. 目前, Internet 主要使用 TCP/IP 协议来进行通信. 用 户. 1、 TCP/IP 协议. 应用层( FTP,HTTP,DHCP 等 ). TCP. UDP. IP. 数据链路层(网卡驱动程序). 传输介质. TCP/IP 协议结构简图. 报头长度. 总数据报文长度. 32位源 IP 地址.

aizza
Download Presentation

网络程序设计

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. TCP/IP协议  协议软件接口-socket  网络程序设计 Windows网络编程--winsock  TCP通信的例子程序  UDP通信的例子程序  参考书籍

  2. 目前,Internet主要使用TCP/IP协议来进行通信 用 户 1、TCP/IP协议 应用层( FTP,HTTP,DHCP等 ) TCP UDP IP 数据链路层(网卡驱动程序) 传输介质 TCP/IP协议结构简图

  3. 报头长度 总数据报文长度 32位源IP地址 32位目的IP地址 可选项 数据 IP层协议:IP数据报文的简化图 1、TCP/IP协议 报头总长:5×4=20字节 IP地址:标识主机的网络接口---网卡

  4. TCP层协议:TCP数据报文的简化图 16位源端口 16位目标端口 32位序数 32位应答序数 1、TCP/IP协议 标志 16位校验和 可选项 数据 端口:标识应用程序,如80—HTTP,21--FTP 标志:SYN,ACK,FIN

  5. UDP层协议:UDP数据报文的简化图 16位源端口 16位目标端口 16位校长度 16位校验和 数据 1、TCP/IP协议

  6. IP、TCP、UDP的关系 IP报文 IP报头 TCP报头 数 据 1、TCP/IP协议 20字节 20字节 IP报头 UDP报头 数 据 20字节 8字节 TCP主要用于有连接的通信:FTP,HTTP等 UDP主要用于无连接的通信:RTP,DNS等

  7. 操作系统 网络 应用 程序 TCP/IP API 2、协议软件接口-socket 目前,有几种可供应用程序使用TCP/IP协议 的API,最为常用的是伯克利大学为UNIX系统 定义的API,这种API现在被称为套接字(socket) 接口,并已成为事实的标准,微软也在其系统 中采用这种标准,称为Windows socket或Winsock

  8. 就象文件描述符是对文件的抽象一样,套接字 是对网络通信的抽象,是由操作系统创建并维护 的一个数据结构。 对文件操作 对套接字操作 2、协议软件接口-socket CFile f = new CFile(); f.read(); f.write(); f.close(); f.open(); ….. Socket s = creat(); s.read(); s.write(); s.close(); s.bind(); …..

  9. 套接字的数据结构 TCP/IP协议族 Family: PF_INET 服务类型 TCP:SOCK_STREAM UDP:SOCK_DGRAM Service: SOCK_STREAM Local IP: 2、协议软件接口-socket Remote IP: Local Port: Remote Port: 套接字有两中不同类型: 流套接字和数据报套接字 面向连接的TCP 无连接的UDP

  10. Socket使用的地址结构 Struct sockaddr_in { short sin_family; //AF_INET地址族unsigned short sin_port; //使用的端口,2字节 struct in_addr sinaddr; //IP地址,4字节 char sinzero[8]; //预留,8字节 } Struct sockaddr { u_short sa_family; //地址族 char sa_data[14]; //地址 } 2、协议软件接口-socket

  11. Socket提供的函数 socket()创建用于网络通信的描述符—套接字 bind()将本地IP地址和协议端口号绑定到套接字 2、协议软件接口-socket listen()将套接字置入监听模式并准备接受连接请求 accept()作好接受客户端连接的准备 connect()连接远程对等实体(服务器) read()接收下一个传入的数据报文 write()发送外发的一个数据报文 close()终止通信并释放套接字占用的资源

  12. Socket编程原理:采用C/S结构 服务器 客户机 进程通信设施 监听 请求 2、协议软件接口-socket 请求 应答 应答 时 间

  13. 服务器 客户机 socket() bind() listen() socket() accept() connect() write() read() read() write() close() close() 2、协议软件接口-socket 流套接字编程时序图(TCP)

  14. 服务器 客户机 socket() socket() bind() bind() 2、协议软件接口-socket readfrom() sendto readfrom() sendto close() close() 数据报套接字编程时序图(UDP)

  15. ①winsock:针对TCP/IP编程的底层API,其部分代 码在winsock.dll,较复杂但灵活性好 ②WinInet:是比winsock更高一层的API,但它只实 用于HTTP,FTP,gopher的客户端程序,不能用 来创建服务器程序。 ③ MFC类:面向对象的API 有: CAsyncSocket,CSocket CInternetSession, CHttpConnection CGopherConnection, CInternetFile CHttpFile, CFtpFile, CGopherFileFind CInternetException等派生类 ④控件:功能强,使用简单,但通常需要图形界面 的支持,如对话框。 3、winsock基础 对winsock的封装 对winInet 的封装

  16. 3.1 Winsock版本 采用Winsock 1的应用必须有Winsock.h 包含文件 使用Winsock 2的应用需要Winsock2.h 包含文件。

  17. 3.2 使用winsock进行通信 初始化/加载 Winsock库 创建socket 使用socket进行通信 关闭socket 清除Winsock库

  18. 3.2 使用winsock进行通信 ①Winsock初始化与结束 每个Winsock 应用都必须加载Winsock DLL的相应版本。 如果调用Winsock 之前,没有加载Winsock 库,这个函数就会返回一个SOCKET_ERROR,错误信息是WSANOTINITIALISED。 加载Winsock 库是通过调用WSAStartup函数实现的。   程序结束退出前,应该释放对Winsock的使用,调用函数WSAcleanup来实现。

  19. 3.2 使用winsock进行通信 WSAStartup初始化Windows Sockets API 应用程序 WSACleanup释放所使用的Windows Sockets DLL

  20. 3.2 使用winsock进行通信 ②错误检查和控制   如果调用一个Winsock 函数,错误情况发生了,就可用WSAGetLastError函数来获得一个代码,这个代码明确地表明发生的状况。   发生错误之后调用这个函数,就会返回所发生的特定错误的完整代码。WSAGetLastError 函数返回的这些错误都已预定义常量值,根据Winsock 版本的不同,这些值的声明不在Winsock .h中,就会在Winsock2.h中。

  21. 3.2 使用winsock进行通信 •   读取当前错误值:每次发生错误时,如果要对具体问题进行处理,那么就应该调用这个函数取得错误代码。函数定义如下: • int WSAGetLastError(void ); • 错误值请自己阅读Winsock2.h。

  22. 4 TCP通信的例子 • 本节讨论TCP协议编程,包括 • TCP服务器端编程 • TCP客户端编程

  23. server.c client.c 开发环境——提供各种函数调用和接口 4.1客户机/服务器模式

  24. 4.1客户机/服务器模式 • 客户机/服务器模式的建立基于以下两点: • 1、非对等作用; • 2、通信完全是异步的。在操作中采取的是主动请示方式: • 服务器方(先启动,并根据请示提供相应服务): • 1、打开一通信通道并告知本地主机,它愿意在某一个公认 •   地址上接收客户请求。 • 2、等待客户请求到达该端口。 • 3、接收到重复服务请求,处理该请求并发送应答信号。 • 4、返回第二步,等待另一客户请求 • 5、关闭服务器。 • 客户方: • 1、打开一通信通道,并连接到服务器所在主机的特定端口。 • 2、向服务器发送服务请求报文,等待并接收应答;继续提 •   出请求…… • 3、请求结束后关闭通信通道并终止。

  25. 4.2面向连接的套接字的系统调用时序图 s:主线程套接字,用于  监听客户端的请求 ns:子线程套接字,用 于与特定的客户端连接

  26. 4.3Winsock函数详述

  27. 4.3.1创建套接字socket() • 创建套接字:(服务器端和客户端) • SOCKET socket ( int af, int type, int protocol ); • 参数: • af:网络地址类型; type:套接字类型; protocol:指定网络协议。

  28. 4.3.2套接字的绑定bind() • 套接字的绑定:将本地地址绑定到所创建的套接字上(服务器端和客户端) • int bind ( • SOCKET s, • const struct sockaddr FAR * name, • int namelen ); • 参数: • S: 是由socket()调用返回的并且未作连接的套接字描述 • 符(套接字号)。 • Name:socket地址结构,为sockaddr结构,一般使用 • sockaddr_in结构,在使用再强制转换为sockaddr • 结构。 • Namelen:地址结构的长度。

  29. 4.3.3套接字的监听listen() • 套接字的监听:(服务器端) • int listen ( SOCKET s, int backlog ) • 参数: • s:一个已绑定但未联接的套接字。 • backlog:指定正在等待联接的最大队列长度, • 这个参数非常重要,因为服务器一般 • 可以提供多个连接。

  30. 4.3.4套接字等待连接accept( ) • 套接字等待连接:(服务器端) • SOCKET accept ( • SOCKET s, • struct sockaddr FAR * addr, • int FAR * addrlen ) • 参数: • s:处于监听模式的套接字。 • sockaddr:接收成功后返回客户端的网络地址。 • addrlen:网络地址的长度。

  31. Winsock 2引入了一个名为WSAAccept的函数。它能根据一个条件函数的返回值,选择性地接受一个连接。这个新函数的定义如下 Winsock2的等待函数WSAAccept的函数 其中,头三个参数与accept的Winsock 1版本是相同的。lpfnCondition参数是指向一个函数的指针,那个函数是根据客户请求来调用的。该函数决定是否接受客户的连接请求。

  32. 4.3.5套接字的连接connect() • 套接字的连接:将两个套接字连结起来准备通信。(客户端) • int connect ( • SOCKET s, • const struct sockaddr FAR * name, • int namelen ) • 参数: • s:欲连结的已创建的套接字。 • name:欲连结的socket地址。 • namelen:为socket地址的结构的长度。

  33. Winsock2的连接函数WSAConnect() 前三个参数和connect API函数的参数是完全一样的。 lpCallerData参数是指向缓冲区的指针,缓冲区内包含客户机向服务器发出的请求连接的数据。 lpCalleeData参数则指向另一个缓冲区,区内包含服务器向客户机返回的建立连接时的数据。这两个参数都是WSABUF结构,因此,若是lpCallerData,len字段应该设为buf字段中准备传输的数据长度。若是lpCalleeData,len字段则代表buf中的缓冲区长度,设为从服务器返回的数据长度。 lpQOS参数用于指定套接字s需要的服务质量,而lpGQOS则用于指定套接字组所需要的服务质量。目前,尚未提供对套接字组的支持。若lpQOS是空值,则表明没有某应用专用的Q O S。

  34. 数据传输 要在已建立连接的套接字上接收数据,可用这两个A P I函数:send和WSASend。第二个函数是Winsock 2中专有的。 在已建立了连接的套接字上接收数据也有两个函数: recv和WSARecv。后者也是Winsock 2函数

  35. 4.3.6 发送数据send() • 发送数据:(服务器端和客户端) • int send ( • SOCKET s, • const char FAR * buf, • int len, int flags ) • 参数: • s:服务器端监听的套接字。 • buf:欲发送数据缓冲区的指针。 • len:发送数据缓冲区的长度。 • flags:数据发送标记。可为0、 • MSG_DONTROUTE或MSG_OOB

  36. Winsock2发送数据WSAsend() int WSASend ( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionROUTINE ); S: 是一个连接会话的有效句柄。 lpBuffers是指向一个或多个WSABUF结构的指针。 dwBufferCount指明准备投递的WSABUF结构数。 lpNumberOfBytesSent是指向DWORD(是WSASend调用返回的)的指 针,其中包含字节总发送数。 dwFlags参数与它在send中的意义相同。 lpOverlapped和lpCompletionROUTINE—用于重叠I/O。 WSASend函数把lpNumberOfBytesSent设为写入的字节数。成功的话,该函数就返回0,否则就返回SOCK_ERROR。

  37. 4.3.7 数据接收recv( ) • 数据接收:(客户端) • int recv ( • SOCKET s, • char FAR * buf, • int len, int flags ) • 参数: • s:准备接收数据的套接字。 • buf:准备接收数据的缓冲区。 • len:准备接收数据缓冲区的大小。 • flags:数据接收标记。: 0、MSG_PEEK、 • MSG_OOB

  38. Winsock2数据接收WSArecv( )

  39. 中断连接 一旦完成任务,就必须关掉连接,释放关联到那个套接字句柄的所有资源。要真正地释放与一个开着的套接字句柄关联的资源,执行closesocket调用即可。 closesocket可能会带来负面影响,即可能会导致数据的丢失。应该在调用closesocket函数之前,利用shutdown函数从容中断连接。

  40. 4.3.8 中断套接字连接shutdown() • 中断套接字连接:通知服务器端或客户端停止接收和发送数据。(服务器端和客户端) • int shutdown ( SOCKET s, int how ) • 参数: • s:欲中断连接的套接字。 • How:描述禁止哪些操作,取值为: • SD_RECEIVE、SD_SEND、SD_BOTH。 • #define SD_RECEIVE 0x00 • #define SD_SEND 0x01 • #define SD_BOTH 0x02

  41. 4.3.9 关闭套接字closesocket() • 关闭套接字: • 释放所占有的资源。(服务器端和客户端) • int closesocket( SOCKET s ) • 参数: • s:欲关闭的套接字。

  42. TCP程序示例 • 服务器上: • Tcp\server.c • Tcp\client.c

  43. 5、无连接协议 • 典型的无连接协议 : UDP • 本节讨论 • 接收端(可称之为服务器) • 发送端

  44. 接收端 1、用socket或WSASocket建立套接字。 2、通过bind函数把这个套接字和准备接收数据   的接口绑定在一起。 3、和面向会话不同的是,我们不必调用listen   和accept。 4、相反,只需等待接收数据。 5、由于它是无连接的,因此始发于网络上任   何一台机器的数据报都可被接收端的套接   字接收。

  45. 5.1接收数据函数recvfrom 1、前面四个参数和recv是一样的,其中包括标志 MSG_OOB和MSG_PEEK。 2、对监听套接字的具体协议来说,from参数是一个 SOCKADDR结构,带有指向地址结构的长度的 fromlen。 3、这个API调用返回数据时,SOCKADDR结构内便填入   发送数据的那个工作站的地址。

  46. Winsock 2接收数据函数WSARecvFrom

  47. 两者的差别在于接收数据的W S A B U F结构的用法上。 利用d w B u ff e r C o u n t为W S A R e c v F r o m提供一个或多个W S A B U F缓冲。提供多个缓冲,就可用发散集合了。 读取的字节总数返回在l p N u m b e r O f B y t e s R e c v d中。 l p F l a g s参数可以是代表无选项的0、MSG_OOB、MSG_PEEK或MSG_PARTIAL。这些标志还可以累加起来。如果在调用这个函数时,指定MSG_PARTIAL,提供者就知道返回数据,即使只收到了部分消息。调用返回之后,如果只收到部分消息,就会设置MSG_PARTIAL标志。再次返回之后,WSARecvFrom就会把lpFrom参数(它是一个指向SOCKADDR结构的指针)设为发送端的地址。 lpFromLen指向SOCKADDR结构的长度,另外,在这个函数中,它还是一个指针,指向DWORD。最后两个参数, lpOverlapped和lpCompletionROUTINE,用于重叠I / O

  48. 发送端    要在一个无连接的套接字上发送数据,有两种选择。    第一种,也是最简单的一种,便是建立一个套接字,然后调用sendto或WSASendTo

  49. 5.2 发送数据 sendto函数 b u f是发送数据的缓冲, l e n指明发送多少字节。 其余参数和r e c v f r o m的参数一样。 t o参数是一个指向SOCKADDR结构的指针,带有接收数据的那个工作站的目标地址。

  50. Winsock 2函数WSASendTo

More Related