1、第11章 网 络 编 程 第11章 网 络 编 程 11.1 套接字概述套接字概述11.2 Winsock函数函数11.3 通信程序设计通信程序设计11.4 基于基于TCP的端口扫描程序的端口扫描程序 第11章 网 络 编 程 11.1 套套接接字字概概述述 11.1.1 Windows Socket简介简介在20世纪80年代,美国加利福尼亚大学Berkeley(伯克利)分校在BSD UNIX系统下实现了通信协议TCP/IP的开发接口Socket(套接字),并很快流行起来,成为主要应用于BSD UNIX系统的通用网络编程接口。Winsock(Windows Socket的简称)就是由Berke
2、ley Socket演变而来的,它定义了Windows系统下的网络编程接口。第11章 网 络 编 程 Windows Socket规范提供给应用程序开发者一套简单的API,并让各个网络软件供应商共同遵守。该规范还定义了应用程序开发者能够使用,并且网络软件供应商能够实现的一套库函数调用和相关语义。遵守这套Windows Socket规范的网络软件,我们称之为Windows Socket兼容的,而Windows Socket兼容实现的提供者,我们称之为Windows Socket提供者。一个网络软件实现Windows Socket规范才能做到与Windows Socket兼容。任何能够与Windo
3、ws Socket兼容的应用程序就被认为是具有Windows Socket接口。Windows Socket规范定义并记录了如何使用API与TCP/IP协议连接,应用程序调用Windows Socket的API实现相互之间的通信,Windows Socket又利用下层的网络通信协议功能和操作系统调用实现实际的通信工作。第11章 网 络 编 程 11.1.2 Winsock基本概念基本概念 1端口端口网络中可以被命名和寻址的通信端口,是操作系统可分配的一种资源。按照OSI体系七层结构的描述,传输层与网络层在功能上的最大区别是传输层提供进程间通信的能力,即网络通信最终是在两个应用进程之间交互的,可
4、以用IP地址来标示一台主机,而一台主机上往往存在多个应用进程,每一个应用进程也需要一个惟一的标识符。为此,TCP/IP协议提出了协议端口(Protocol Port,简称端口)的概念,用于标识通信的应用进程。端口是一种抽象的软件结构(包括一些数据结构和I/O缓冲区)。第11章 网 络 编 程 应用进程通过系统调用与某端口建立连接后,传输层传给该端口的数据都被相应进程所接收,且相应进程发给传输层的数据通过该端口输出。在TCP/IP协议的实现中,端口操作类似于一般的I/O操作,进程获取一个端口,相当于获取本地惟一的I/O文件,可以用一般的读写原语访问。类似于文件描述符,每个端口都拥有一个称为端口号
5、(Port Number)的整数型标识符,用于区别不同端口。端口号的分配是一个重要问题,有两种基本分配方式:第一种叫全局分配,这是一种集中控制方式,由一个公认的中央机构根据用户需要进行统一分配,并将结果公布于众;第11章 网 络 编 程 第二种是本地分配,又称动态连接,即进程需要访问传输层服务时,向本地操作系统提出申请,操作系统返回一个本地惟一的端口号,进程再通过合适的系统调用将自己与该端口号联系起来(绑定)。TCP/IP端口号的分配中综合了上述两种方式。TCP/IP将端口号分为两部分,少量的作为保留端口,以全局方式分配给服务进程。因此,每一个标准服务器进程都拥有一个全局公认的端口号(即周知端
6、口,Well-Known Port),即使在不同机器上,其端口号也相同。剩余的为自由端口,以本地方式进行分配。TCP和UDP均规定,小于1024的端口号才能作为保留端口。第11章 网 络 编 程 2套接字套接字套接字是支持TCP/IP协议网络通信的基本操作单元。一个套接字是通信的一个端点,通常由一个与进程相关联的端口号以及主机的IP地址来标识。一个正在被使用的套接字有自己的类型和与其相关的进程,相互交互的两个进程通过各自的套接字进行通信。套接字存在于通信域(即地址族)中,是为了处理线程间通信而引进的抽象概念,一般情况下通信发生在同一通信域中的套接字之间,Winsock规范只支持单一的通信域,即
7、Internet域。套接字可以根据通信的性质进行分类,并且按这种方法可分为两类:流式套接字和数据报套接字。应用程序一般仅在同一类套接字之间通信。第11章 网 络 编 程 3字节顺序字节顺序不同的计算机使用不同的字节顺序存储数据。Intel处理器使用的字节顺序称为“Little-Endian”,即高字节在前,低字节在后;而Internet网络的字节顺序称为“Big-Endian”,它和Little-Endian的字节顺序是相反的。因此用户在使用时要特别注意字节的正确顺序。第11章 网 络 编 程 任何Winsock函数对IP地址和端口号的使用均是按照网络字节顺序组织的。在很多情况下,用户要在本地
8、主机字节顺序和网络字节顺序之间进行转换,此时应该使用Winsock API中标准的转换函数,而不要自己编写转换代码。因为将来的Winsock实现有可能在本地主机字节顺序和网络字节顺序相同的机器上运行,因此只有使用标准的转换函数应用程序才可以移植。为了统一起见,通常无论本地主机字节顺序与网络字节顺序是否一致,在进行网络传输时都将本地主机字节顺序转换成网络字节顺序,在接收时再将网络字节顺序转换成本地主机字节顺序。第11章 网 络 编 程 4阻塞和非阻塞套接字可以处于阻塞模式或非阻塞模式。在阻塞模式下,I/O操作完成前,执行操作的Winsock函数会一直等待下去,不会立即返回,这就意味着任一个线程在
9、某一时刻只能执行一个I/O操作,而且应用程序很难同时通过多个建好连接的套接字进行通信;而非阻塞模式下没有这样的要求,Winsock函数无论如何都会返回并交出程序的控制权。在默认的情况下,套接字处于阻塞模式。第11章 网 络 编 程 5错误检查与控制要成功编写Winsock应用程序,错误检查和控制是至关重要的。因为对于Winsock函数而言,返回错误值是非常常见的。但是多数情况下,这些错误是无关紧要的,通信仍可在套接字上进行。返回的错误值可以有多种,但最常见的错误是SOCK_ERROR。SOCK_ERROR的值是-1,但这个值仅仅是函数的返回值,由此还不能看出错误的具体类型。要想获得具体的错 误
10、 代 码,还 必 须 在 调 用 W i n s o c k 函 数 之 后,用WSAGetLastError函数来获得错误代码,这个错误代码能明确地表明产生错误的原因。该函数的定义为int WSAGetLastError(void);第11章 网 络 编 程 11.2 Winsock函数函数 11.2.1 Winsock 初始化函数初始化函数1WSAStartup()WSAStartup()函数用于在应用程序中初始化Windows Sockets DLL,只有此函数调用成功后,应用程序才可以再调用其他Windows Sockets DLL中的API函数。此函数若调用成功,则返回0,否则返回错
11、误。第11章 网 络 编 程 函数原型:int PASCAL FAR WSAStartup(WORD wVersionRequested,LPWSADATA lpWSAData);参数说明:wVersionRequested:用于指定Windows Sockets API版本。lpWSAData:是指向WSADATA 结构的指针,WSAData结构用来存储系统返回的关于Winsock的信息。第11章 网 络 编 程 2WSACleanup()WSACleanup()函数用于结束对Winsock DLL的使用,并释放资源,该函数不带任何参数,若调用成功则返回0,否则返回错误。调用格式:int W
12、SACleanup(void);第11章 网 络 编 程 11.2.2 基本基本Winsock函数函数 1socket()初始化Winsock的动态链接库后,可以调用socket()函数来建立Socket,并定义此Socket所使用的通信协议。此函数调用成功返回Socket对象,失败则返回INVALID_SOCKET(调用WSAGetLastError()函数可得知原因,所有Winsock的函数都可以使用这个函数来获取失败的原因)。函数原型:SOCKET socket(int af,int type,int protocol);第11章 网 络 编 程 参数说明:af:指协议簇,对于TCP/I
13、P协议,为AF_INET;type:Socket的类型,如果是TCP则为SOCK_STREAM,是UDP则为SOCK_DGRAM;protocol:使用的通信协议,可以指定为IPPROTO_IP、IPPROTO_UDP等,如果使用者不指定,默认为0,表示为TCP/IP协议,例如:s=socket(AF_INET,SOCK_STREAM,0);注释:Winsock API 是建立在套接字基础上的。套接字从实质上讲,就是一个指向传输提供者的句柄。Win32中套接字不同于其他文件描述符,它是一个独立的类型Socket。第11章 网 络 编 程 2bind()把定义的Socket同一个地址绑定,要调用
14、bind()函数,该函数调用成功返回0,否则返回SOCKET_ERROR。函数原型:int bind(SOCKET s,const struct sockaddr FAR *name,int namelen);参数说明:s:Socket对象名;name:指向类型为struct sockaddr的套接字地址结构的指针。namelen:name的长度。第11章 网 络 编 程 struct sockaddr定义如下:struct sockaddr unsigned short sa_family;char sa_data14;第11章 网 络 编 程 sa_family地址族,一般为AF_INET
15、;sa_data则包含该Socket的IP地址和端口号。另外还有一种结构类型定义如下:struct sockaddr_in short int sin_family;unsigned short int sin_port;struct in_addr sin_addr;unsigned char sin_zero8;第11章 网 络 编 程 这个结构使用更为方便。sin_family通常被赋AF_INET;sin_port指端口号;sin_addr 填入IP地址;sin_zero,用来将sockaddr_in结构的长度填充到与struct sockaddr同样的长度。如果使用者不在意地址或端口
16、的值,那么可以设定sin_addr为INADDR_ANY,sin_port为0,Windows Socket会自动设置一个地址及端口值(10245000之间的值),通常在客户端编程时采用。此后可以调用getsockname()函数来获知其被设定的值。第11章 网 络 编 程 注释:bind()函数将指定的套接字同一个已知地址和端口绑定在一起。一旦出错,bind()函数会返回SOCKET_ERROR。对bind()函数来说,最常见的错误是WSAEADDRINUSE,表示另一个进程已经同本地IP和端口号绑定在一起,或者本地IP和端口号处于TIME_WAIT状态。假如对一个已绑定套接字调用bind(
17、)函数,便会返回WSAEFAULT错误。第11章 网 络 编 程 3listen()listen()函数使Socket进入监听状态,并设定可以建立的 最 大 连 接 数。该 函 数 调 用 成 功 返 回 0,否 则 返 回SOCKET_ERROR。函数原型:int listen(SOCKET s,int backlog);参数说明:s:需要建立监听的Socket。第11章 网 络 编 程 backlog:正在等待连接的最大队列长度;在服务器端该参数的设置非常重要,因为可能同时有多个客户端同时向服务器发出连接请求。客户端的请求会存放在服务器的“等待处理”队列中。服务器端的Socket调用完li
18、sten()函数后,如果此时客户端调用connect()函数提出连接请求,则客户端的请求信息会存放在服务器端的“等待处理”队列中。接下来,服务器端必须调用accept()函数,从“等待处理”队列中提取客户端的请求信息进行处理,这样服务器端和客户端才算正式完成了通信程序的连接动作。第11章 网 络 编 程 4accept()当客户提出连接请求时,为了使服务器端接受客户端的连接请求,就要使用accept()函数,该函数新建一个Socket与客户端的Socket相通,原先监听的Socket继续进入监听状态,等待其他连接要求。该函数调用成功,返回一个新产生的Socket对象,否则返回INVALID_S
19、OCKET。函数原型:SOCKET accept(SCOKET s,struct sockaddr FAR*addr,int FAR*addrlen);参数说明:s:已经建立的、处在监听模式的Socket;第11章 网 络 编 程 addr:存放请求连接的客户端的地址;addrlen:addr的长度。注释:accept()函数返回一个新的套接字,其中addr参数变量中会包含发出连接请求的客户机的地址信息,而addrlen参数指出该结构的长度。对于该客户端后续的所有操作,都应使用这个新套接字。至于原来那个套接字,它仍然用于接受其他客户端的连接,而且仍然处于侦听状态。如果有新的连接请求,可以通过a
20、ccept()函数的再一次调用而获得接受;否则,服务进程被阻塞。如果调用accept()函数出错,会返回INVALID_SOCKET,如果要获得具体错误代码可以调用WSAGetLastError()函数。第11章 网 络 编 程 5Connect()客户端的Socket使用connect()函数来提出与服务器端的Socket建立连接的申请,函数调用成功返回0,否则返回SOCKET_ERROR。函数原型:int connect(SOCKET s,const struct sockaddr FAR*name,int namelen);参数说明:s:标识一个还未连接的Socket;name:Sock
21、et想要连接的对方的地址信息;namelen:name的长度。第11章 网 络 编 程 6closesocket()结束服务器和客户端的通信连接是很简单的,这一过程可以由服务器或客户机的任一端启动,只要调用closesocket()函数即可,而要关闭Server端监听状态的Socket,同样也是利用此函数。另外,与程序启动时调用WSAStartup()函数相对应,程序结束前,需要调用 WSACleanup()函数来通知Winsock Stack释放Socket所占用的资源。这两个函数都是调用成功返回0,否则返回SOCKET_ERROR。第11章 网 络 编 程 函数原型:int closeso
22、cket(SOCKET s);参数说明:s:准备关闭的Socket。注释:closesocket()函数的调用会释放套接字句柄s,以后再对该套接字的访问均以WSAENOTSOCK错误返回。第11章 网 络 编 程 7shutdown()shutdown()函数用于禁止在一个套接字上进行数据的接收与发送。函数原型:int shutdown(SOCKET s,int how);参数说明:s:被禁止的Socket。how:标志,用于描述禁止哪些操作。可能的取值是SD_REVIEVE,SD_SEND或SD_BOTH。SD_RECEIVE表示不允许再调用接收函数;SD_SEND表示不允许再调用发送函数。
23、SD_BOTH表示取消连接两端的收发操作。第11章 网 络 编 程 11.2.3 数据传输函数数据传输函数1send()send()函数用于在套接字连接成功的情况下发送数据。函数原型:int send(SOCKET s,const char FAR*buf,int len,int flags);参数说明:s:已连接的Socket;buf:存放要传送资料的缓冲区的地址;len:buf的长度;flags:此函数被调用的方式。第11章 网 络 编 程 2recv()recv()函数用于在套接字连接成功的情况下接收数据。函数原型:int recv(SOCKET s,char FAR*buf,int l
24、en,int flags);参数说明:s:已连接的Socket;buf:存放接收到的资料的缓冲区;len:buf的长度;flags:此函数被调用的方式。第11章 网 络 编 程 3sendto()sendto()函数用于向一指定目的地发送数据。函数原型:int sendto(SOCKET s,const char FAR*buf,int len,int flags,const struct sockaddr FAR*to,int tolen);参数说明:s:表示Socket。buf:待发送数据的缓冲区。len:待发送的字节数。第11章 网 络 编 程 flags:调用方式标志位,可以为0、MS
25、G_DONTROUTE、MSG_OOB或这些标志按位“或”运算的结果。MSG_DONTROUTE用于告知IP协议,目的主机在本地网络,没有必要查找路由表,可以将报文直接传送给目的地址。这个标志一般用在网络诊断和路由程序里面。MSG_OOB标志数据应被带外发送,带外数据指TCP紧急数据。to:指针,指向目的套接字的地址结构。tolen:to所指地址结构的长度。第11章 网 络 编 程 4 4recvfrom()recvfrom()recvfrom()函数用于接收一个数据报并保存、发送地方地址结构信息。函数原型:int recvfrom(SOCKET s,const char FAR*buf,in
26、t len,int flags,struct sockaddr FAR*from,int FAR*fromlen);参数说明:s:表示Socket。buf:接收数据缓冲区。len:准备接收的字节数或buf缓冲区长度。第11章 网 络 编 程 flags:调用操作方式,可以为0、MSG_PEEK、MSG_OOB或这些标志按位“或”运算的结果。其中:0表示无特殊行为;MSG_PEEK使有用的数据复制到提供的接收端缓冲区内,但没有把它从系统缓冲区中删除。from:指针,发送方套接字地址结构信息。fromlen:指针,指向SOCKADDR地址结构的长度。注释:recvfrom()函数调用成功则返回实际
27、接收的字节数,发生错误时,返回-1。第11章 网 络 编 程 11.2.4 网络信息查询函数网络信息查询函数 1getpeername()getpeername()获取通信对方的套接字地址结构信息。函数原型:int getpeername(SOCKET s,struct sockaddr FAR*name,int FAR*namelen);参数说明:s:已连接的socket;name:通信对方的套接字地址结构;namelen:指向地址结构长度的指针。第11章 网 络 编 程 2getsockname()getsockname()函数是getpeer的对应函数,用于获取指定套接字的本地地址结构信
28、息。函数原型:int getsockname(SOCKET s,struct sockaddr FAR*name,int FAR*namelen);参数说明:s:标示一个已绑定套接字的句柄;name:套接字的地址结构;namelen:指向地址结构长度的指针。第11章 网 络 编 程 3gethostbyname()gethostbyname()函数用于返回对应于给定主机名的主机信息,在已知主机名并打算查找其IP时,可以使用该函数。函数原型:struct hostent FAR*gethostbyname(const char FAR*name);参数说明:name:指向主机名的指针。第11章
29、网 络 编 程 4gethostbyaddr()gethostbyaddr()函数用于返回对应于给定IP地址的主机信息,在已知IP地址并打算查找其主机名时,可以使用该函数。函数原型:struct hostent FAR*gethostbyaddr(const char FAR*addr,int len,int type);第11章 网 络 编 程 参数说明:addr:指向网络字节顺序IP地址的指针;len:地址的长度,在AF_INET类型地址为4;type:地址类型,应为AF_INET。注释:gethostbyaddr()函数返回对应于给定IP地址的包含主机名字和地址信息的hostent结构指
30、针。第11章 网 络 编 程 5getservbyname()getservbyname()函数用于返回对应于给定服务名字和协议名的相关服务信息,在已知服务的情况下,要查找其对应的端口号,可以使用该函数。函数原型:sturct servent FAR*getservbyname(const char FAR*name,const char FAR*proto);参数说明:name:指向服务名的指针;proto:指向协议名的指针。第11章 网 络 编 程 11.3 通信程序设计通信程序设计 11.3.1 客户客户/服务器模式服务器模式网络应用进程自身功能的实现往往是通过存在于不同主机中的多个应用
31、进程间的通信和协同工作来完成的。客户和服务器是通信中涉及的两个应用进程。客户是主动请求服务的一方,服务器是接受请求,提供服务的一方。一个服务器进程通常在一个众所周知的端口监听是否有客户的请求到达,即服务器进程总是处于等待状态,直到某一客户进程发出的请求到来,此时,服务器进程开始响应客户的请求,为客户提供服务。第11章 网 络 编 程 11.3.2 面向连接服务和无连接服务面向连接服务和无连接服务1面向连接服务面向连接服务在面向连接的服务中,通信双方在进行数据交换之前,必须先建立一条连接,数据传输结束后释放连接。面向连接服务确定通信双方之间存在连接,保证通信双方处于活动状态,且数据是按序传送的,
32、从而保证了数据通信的可靠性。面向连接的服务只支持点到点通信。面向连接服务比较适合于在一段时间间隔内向同一目的地发送大量报文的情况。对于发送少量零星报文的情况,连接的建立和释放所带来的开销就显得过大了。第11章 网 络 编 程 2无连接服务无连接服务在无连接服务中,发送方可以随时发送数据而无需事先建立连接。发送方并不清楚接收方的状态以及网络中是否有路径可以到达接收方,因此数据包可能会丢失,且由于前后数据的传输路径可能不同,因此无法保证数据按序到达目的地。这些问题留给应用程序自行解决。无连接服务可以实现点对点通信以及点对多点通信,适合于少量零星报文的传送以及对传输的可靠性没有要求的应用。第11章
33、网 络 编 程 11.3.3 流式套接字和数据报套接字流式套接字和数据报套接字1流式套接字流式套接字流式套接字提供双向、有序、无重复并且无报文段边界的数据流服务,即一种可靠的面向连接的数据传输方法。流式套接字使用TCP协议,当要发送大批量数据或要保证数据按顺序、无重复地到达目的地时,需要使用流式套接字。流式套接字是面向连接的,因此服务器进程和客户进程在通信前必须建立各自的套接字,并进行连接,然后才能对相应的套接字进行“读”、“写”操作,实现数据的传输。流式套接字编程的流程如图11.1所示。第11章 网 络 编 程 图11.1 流式套接字编程流程 建立套接字socket()服务器程序绑定套接字b
34、ind()侦听listen()准备接受连接accept()阻塞、等待建立连接发送/接收数据send to()/recy from()关闭closesocket()建立套接字socket()关闭closesocket()客户程序数据传送建立连接connect()接收/发送数据recy from()/send to()第11章 网 络 编 程 2数据报套接字数据报套接字数据报套接字支持双向通信,提供不可靠的、无连接的数据报通信方式。也就是说,一个从数据报套接字接收信息的进程可能发现信息重复、接收顺序与发送顺序不同等情况,接收程序应具有处理这些情况的能力。数据报套接字使用UDP协议,具有向多个目标地
35、址发送广播数据报的能力。数据报套接字是无连接的,它不能保证接收端是否正在等待接收,因此,数据报并不十分可靠,需要应用程序负责管理数据报的排序和可靠性。数据报套接字的编程过程比流式套接字简单。数据报套接字编程使用的基本函数与流式套接字使用的函数一样,而数据传输函数则不同:发送数据使用sendto()函数,接收数据使用recyfrom()函数。第11章 网 络 编 程 图11.2 数据报套接字编程流程建立套接字socket()服务器程序建立套接字socket()客户程序数据传送关闭closesocket()发送/接收数据sendto()/recyfrom()绑定套接字bind()关闭closeso
36、cket()接收/发送数据recyfrorn()/sendto()绑定套接字bind()第11章 网 络 编 程 11.3.4 实验实验 面向连接通信程序面向连接通信程序1实验要求实验要求(1)掌握网络编程的概念。(2)通过程序设计理解流式套接字编程流程。2实验设备计算机1台。第11章 网 络 编 程 3实验过程和主要步骤实验过程和主要步骤(1)服务器。服务器程序先运行,首先初始化Winsock,然后创建套接字,在2000端口上进行绑定,接着在2000端口上进行侦听,并进入等待连接状态。当与客户建立连接后,服务器接收客户发来的文件,并将其放在相应位置。以上过程的实现程序如下:#include
37、stdafx.h#include winsock.h#include windows.h#include stdio.h 第11章 网 络 编 程#pragma comment(lib,wsock32.lib)#define RECV_PORT 2000#define SEND_PORT 3000#define MAX_FILESIZE 32*1024 SOCKET sock,sock1;sockaddr_in ServerAddr;sockaddr_in ClientAddr;struct Filedata 第11章 网 络 编 程 char ffname30;char ffdataMAX_
38、FILESIZE;int len;DataPacket;int Addrlen;DWORD StartSock()WSADATA WSAData;if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0)第11章 网 络 编 程 printf(sock init fail!n);return(-1);return(1);DWORD Createsocket()sock=socket(AF_INET,SOCK_STREAM,0);if(sock=SOCKET_ERROR)printf(sock create fail!n);WSACleanup();return(-1);
39、第11章 网 络 编 程 ServerAddr.sin_family=AF_INET;ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY);ServerAddr.sin_port=htons(RECV_PORT);if(bind(sock,(struct sockaddr FAR*)&ServerAddr,sizeof(ServerAddr)=SOCKET_ERROR)printf(bind is the error);return(-1);return(1);第11章 网 络 编 程 DWORD WriteFile(char*fname,char*fdat
40、a,int flen)int i;FILE*fp;fp=fopen(fname,w);if(fp=NULL)printf(cannot open this iflen);i=0;for(i=0;iflen;i+)fputc(fdatai,fp);第11章 网 络 编 程 fclose(fp);return(1);DWORD ConnectProcess()Addrlen=sizeof(sockaddr_in);if(listen(sock,5)0)printf(Listen error);return(-1);printf(listening.n);第11章 网 络 编 程 for(;)soc
41、k1=accept(sock,(struct sockaddr FAR*)&ClientAddr,&Addrlen);if(sock1!=-1)printf(Accepted a connection!n);for(;)memset(DataPacket.ffname,0,30);memset(DataPacket.ffdata,0,MAX_FILESIZE);DataPacket.len=0;第11章 网 络 编 程 if(recv(sock1,(char*)&DataPacket,sizeof(DataPacket),0)MAX_FILESIZE)printf(your file is t
42、oo bign);fclose(fp);return(0);memcpy(&Senddatai,buffer,count);i+=count;第11章 网 络 编 程 fclose(fp);Senddatai=0;strcpy(DataPacket.ffname,fname);memcpy(DataPacket.ffdata,Senddata,Filesize);DataPacket.len=Filesize;printf(%s%dn,DataPacket.ffname,DataPacket.len);return(1);DWORD TCPSendPacket(struct Filedata
43、Packet)第11章 网 络 编 程 int length;length=send(sock,(char*)&Packet,sizeof(DataPacket),0);if(lengthdwValue;aroutdwValue;aroutCreate()第11章 网 络 编 程/如果创建失败,则删除,返回 falsedelete psocket;psocket=NULL;return FALSE;/连接被连接的主机地址和指定端口while(!psocket-Connect(IP,nPort)/如果失败返回falsedelete psocket;psocket=NULL;return FALS
44、E;第11章 网 络 编 程/关闭socketpsocket-Close();delete psocket;return TRUE;第11章 网 络 编 程 11.4.3 实验实验 基于基于TCP的端口扫描程序设计的端口扫描程序设计1实验要求实验要求(1)理解端口扫描的原理。(2)掌握VC/JAVA中Socket编程的类库。(3)完成端口扫描的程序设计,要求有完善的界面设计。第11章 网 络 编 程 2实验设备一台连接到网络环境的计算机。3实验过程及主要步骤(1)学习基于Socket编程的基本技术。(2)学习与端口扫描的相关类库。(3)参考上述流程图,设计出完整的流程图(读者完成)。(4)编程、调试,并验证(读者完成)。
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。