《安全扫描》课程设计报告

上传人:1888****888 文档编号:39265766 上传时间:2021-11-10 格式:DOC 页数:48 大小:1.48MB
返回 下载 相关 举报
《安全扫描》课程设计报告_第1页
第1页 / 共48页
《安全扫描》课程设计报告_第2页
第2页 / 共48页
《安全扫描》课程设计报告_第3页
第3页 / 共48页
点击查看更多>>
资源描述
安全扫描课程设计报告姓 名: 学 号: 学 院: 信息科学技术学院 成 绩: 任课教师: 目 录摘 要 -11.引言 -11.1开发背景 -11.2 设计题目及要求-12.程序的编译与开发 -22.1 开发目的 -22.2 开发环境及工具-22.3 开发过程-23.基本思路及所涉及的相关理论 -23.1基本思路-23.2相关理论-2 3.2.1协议介绍 -2 3.2.2 TCP实现流程-33.2.3 UDP实现流程-53.2.4 Windows Socket 套接字编程原理-64.实验过程-105、个人感想与感悟 - 23附录(程序代码部分)-23附录一:(基于TCP通信的客户端与服务器)-23附录二:(基于UDP通信的客户端与服务器)-29附录三:(基于 TCP/UDP 的网络安全扫描) -38摘 要计算机信息网络的发展加速了信息化时代的进程,但是随着社会网络化程度的增加,对计算机网络的依赖也越来越大,网络安全问题也日益明显。端口扫描技术室发现安全问题的重要手段之一。当前进行网络端口扫描的主要技术有:基于ARP、ICMP、TCP(包括TCP connect扫描、TCP SYN扫描、TCP ACK 扫描、TCP FIN扫描等)、UDP 网络协议的网络活动端口扫描。(1)、利用ARP协议获取活动主机的MAC地址,当获取的不为“00-00-00-00-00-00”时,则认为当前主机可达,是活动的主机;(2)、利用ICMP协议,使用系统自带的PING程序,当能PING 通目标主机时,认为是活动主机(能扫描到活动的端口);(3)、基于TCP的链接状态当判断链接成功认为主机可到达(并能扫描到相应的端口);(4)、基于UDP 的不可靠传输,我们可以通过套接字编程给目标主机发送消息,能够得到返回消息,则认为主机可到达(相应扫描到端口)。根据以上方法,我们均能扫描到开放的端口,因此,我们同样可以做到对自己电脑的自纠自查,对自己的主机实施相应的网络安全保护。关键字:TCP连接 套接字 TCP/UDP端口扫描.客户端、服务器及网络安全扫描的实现1.引言1.1开发背景 端口扫描,顾名思义,就是对目标主机的端口依次进行连接,对于能进行数据通信的,则认为是”开”状态,否则认为是”关”状态。由于绝大部分公用服务于端口有对应关系,因此通过端口的”开”与”关”状态,可以初步判断对方是否提供相应的服务,为下一步的操作提供参考。 端口是一个传输层的概念,因此端口扫描也仅限于在传输层上进行,传输层一般将协议分为TCP协议和UDP协议,所以端口扫描也根据扫描所采用的类型分为TCP端口扫描、UDP端口扫描两大类。 端口扫描与其说是一种攻击方法,不如说是一种检测方法,因为通过端口扫描,即使是知道对方哪些端口是开的,也不意味着对方就一定提供了这些端口对应的服务,更谈不上能查出什么漏洞。但黑客正是用端口扫描预测一台主机上都提供了哪些服务,如果所提供的这些服务存在漏洞,黑客就会利用这些漏洞对系统进行攻击。而事实上即使没有什么漏洞可找,仅就扫描所得的信息,就已经给黑客提供大量的重要信息,因此端口扫描往往作为黑客攻击的第一步。所以,对于任何一个拥有电脑的用户完全有必要对端口进行详细地了解,对于没有实质性作用的端口要关闭,对于必须开放的端口则尽可能地安装其漏洞补丁程序。1.2 设计题目及要求(1)、至少建立TCP/UDP两台服务器服务器端口和服务必须有公开和保密(后门)两类。(2)、完成TCP/UDP协议客户端扫描程序可以扫描出公开和保密的全部端口号,确定全部公开的服务,甚少可以确定一种保密的服务。(3)、可以扫描顾剑老师上课的服务器210.37.47.194,检查其安全情况。(4)、可以扫描 服务器,检查其安全情况。(5)、同学之间可以互相扫描各自的服务器,检查其服务情况。(6)、不可扫描其他境内服务器。(7)、写出完整的试验报告,并尝试给出一些防范和修改建议。2.程序的编译与开发2.1 开发目的1.了解和掌握TCP/IP协议的基本原理(TCP通信、UDP通信);2.了解网络环境下的程序设计步骤和过程;3.掌握Winsock提供函数的功能和用法。2.2 开发环境及工具测试平台:Windows XP Professional使用软件:Microsoft Visual C+ 6.0开发语言:C语言2.3 开发过程根据题目的要求,结合相应的算法理论及相关的基础知识,在Microsoft Visual C+ 6.0的平台下进行开发。具体过程参见下述的算法理论部分和程序流程步骤的分析。3.基本思路及所涉及的相关理论3.1基本思路 根据题目要求,逐步解析题目含义。实际上,该题目包含三个主要程序:基于TCP客户端和服务器间的通信;基于UDP客户端与服务器的通信;基于TCP和UDP的网络活动端口扫描。由所学知识可知:TCP属于面向连接型协议(可靠传输,通过三次握手连接完成),UDP属于不可靠传输。在Windows平台上,需要通过Winsock套接字编程来实现。3.2相关理论3.2.1协议介绍(1)TCP TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协议/网间协议,是一个工业标准的协议集,它是为广域网(WAN)设计的。它是由ARPANET网的研究机构发展起来的。 有时我们将TCP/IP描述为互联网协议集InternetProtocolSuite,TCP和IP是其中的两个协议(后面将会介绍)。由于TCP和IP是大家熟悉的协议,以至于用TCP/IP或IP/TCP这个词代替了整个协议集。这尽管有点奇怪,但没有必要去争论这个习惯。例如,有时我们讨论NFS是基于TCP/IP时,尽管它根本没用到TCP(只用到IP和另一种交互式协议UDP,而不是TCP)。 TCP/IP的标准在一系列称为RFC的文档中公布。文档由技术专家、特别工作组、或RFC编辑修订。公布一个文档时,该文档被赋予一个RFC编号,如RFC959(FTP的说明文档)、RFC793(TCP的说明文档)、RFC791(IP的说明文档)等。最初的RFC一直保留而从来不会被更新,如果修改了该文档,则该文档又以一个新号码公布。因此,重要的是要确认你拥有了关于某个专题的最新RFC文档。通常在RFC的开头部分,有相关RFC的更新(update)、修改(errata)、作废(obsolete)信息,提示读者信息的时效性。详情请阅读网站RFC-editor1。(2)UCPUDP协议的全称是用户数据包协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。 与所熟知的TCP(传输控制协议)协议一样,UDP协议直接位于IP(网际协议)协议的顶层。根据OSI(开放系统互连)参考模型,UDP和TCP都属于传输层协议。UDP协议的主要作用是将网络数据流量压缩成数据包的形式。一个典型的数据包就是一个二进制数据的传输单位。每一个数据包的前8个字节用来包含报头信息,剩余字节则用来包含具体的传输数据。3.2.2 TCP实现流程:图 3.2.1-1面向连接(TCP)的socket工作流程图3.2.1-2 TCP正常连接过程图3.2.1-3 TCP正常终止连接过程 图 3.2.1-4 TCP 连接过程3.2.3 UDP实现流程:图 3.2.2-1 UDP工作过程图 3.2.2-2 UDP扫描过程3.2.4 Windows Socket 套接字编程原理一、客户机/服务器模式在TCP/IP网络中两个进程间的相互作用的主机模式是客户机/服务器模式(Client/Server model)。该模式的建立基于以下两点:1、非对等作用;2、通信完全是异步的。客户机/服务器模式在操作过程中采取的是主动请示方式:首先服务器方要先启动,并根据请示提供相应服务:(过程如下)1、打开一个通信通道并告知本地主机,它愿意在某一个公认地址上接收客户请求。2、等待客户请求到达该端口。3、接收到重复服务请求,处理该请求并发送应答信号。4、返回第二步,等待另一客户请求5、关闭服务器。客户方:1、打开一个通信通道,并连接到服务器所在主机的特定端口。2、向服务器发送服务请求报文,等待并接收应答;继续提出请求3、请求结束后关闭通信通道并终止二、套接字1. 套接字地址结构(1)、sockaddr结构:struct sockaddru_short sa_family; /* address family */char sa_data14; /* up to 14 bytes of direct address */; sa_family为网络地址类型,一般为AF_INET,表示该socket在Internet域中进行通信,该地址结构随选择的协议的不同而变化,因此一般情况下另一个与该地址结构大小相同的sockaddr_in结构更为常用,sockaddr_in结构用来标识TCP/IP协议下的地址。换句话说,这个结构是通用socket地址结构,而下面的sockaddr_in是专门针对Internet域的socket地址结构。(2)、sockaddr_in结构struct sockaddr_in short sin_family;u_short sin_port;struct in_addr sin_addr;char sin_zero8;sin _family为网络地址类型,必须设定为AF_INET。sin_port为服务端口,注意不要使用已固定的服务端口,如HTTP的端口80等。如果端口设置为0,则系统会自动分配一个唯一端口。sin_addr为一个unsigned long的IP地址。sin_zero为填充字段,纯粹用来保证结构的大小。2套接字的使用步骤(1)、启动Winsock:对Winsock DLL进行初始化,协商Winsock的版本支持并分配必要的资源。(服务器端和客户端)。(2)、创建套接字:(服务器端和客户端)SOCKET socket( int af, int type, int protocol );、af为网络地址类型,一般为AF_INET,表示在Internet域中使用。、type为套接字类型,前面已经介绍了。、protocol为指定网络协议,一般为IPPROTO_IP。(3)、套接字的绑定:将本地地址绑定到所创建的套接字上。(服务器端和客户端)int bind( SOCKET s, const struct sockaddr FAR * name, int namelen )、s为已经创建的套接字。、name为socket地址结构,为sockaddr结构,如前面讨论的,我们一般使用sockaddr_in结构,在使用再强制转换为sockaddr结构。、namelen为地址结构的长度。(4)、套接字的监听:(服务器端)int listen(SOCKET s, int backlog )、s为一个已绑定但未联接的套接字。、backlog为指定正在等待联接的最大队列长度,这个参数非常重要,因为服务器一般可以提供多个连接。(5)、套接字等待连接:(服务器端)SOCKET accept( SOCKET s, struct sockaddr FAR * addr, int FAR * addrlen )、s为处于监听模式的套接字。、sockaddr为接收成功后返回客户端的网络地址。、addrlen为网络地址的长度。(6)、套接字的连接:将两个套接字连结起来准备通信。(客户端)int connect(SOCKET s, const struct sockaddr FAR * name, int namelen )、s为欲连结的已创建的套接字。、name为欲连结的socket地址。、namelen为socket地址的结构的长度。(7)、套接字发送数据:(服务器端和客户端)int send(SOCKET s, const char FAR * buf, int len, int flags )、s为服务器端监听的套接字。、buf为欲发送数据缓冲区的指针。、len为发送数据缓冲区的长度。、flags为数据发送标记。、返回值为发送数据的字符数。(8)、套接字的数据接收:(客户端)int recv( SOCKET s, char FAR * buf, int len, int flags )、s为准备接收数据的套接字。、buf为准备接收数据的缓冲区。、len为准备接收数据缓冲区的大小。、flags为数据接收标记。、返回值为接收的数据的字符数。(9)、中断套接字连接:通知服务器端或客户端停止接收和发送数据。(服务器端和客户端)int shutdown(SOCKET s, int how)、s为欲中断连接的套接字。、How为描述禁止哪些操作,取值为:SD_RECEIVE、SD_SEND、SD_BOTH。(10)、关闭套接字:释放所占有的资源。(服务器端和客户端)int closesocket( SOCKET s )、s为欲关闭的套接字三、典型过程图1. 面向连接的套接字的系统调用时序图图 3.2.3-12.无连接协议的套接字调用时序图图 3.2.3-24、实验过程(1)、至少建立TCP/UDP两台服务器服务器端口和服务必须有公开和保密(后门)两类。一、TCP服务器、公开服务:在与客户端进行连接时,能够接收客户端发送过来的消息。并返回相同的消息以响应客户端,同时日志文件将会记录这一切:(如图4-1所示)图 4-1 公开服务接收信息、保密服务:当客户端发送停机密码时,服务器会自动关机,不对任何客户端提供服务:(图4-2、图4-3)图 4-2(收到停机密码的服务器)图 4-3(发送了停机密码的客户端)二、UCP服务器、公开服务:能够接收客户端发送过来的消息,并响应客户端,同时日志文件将会记录这一切:(如图4-4所示)图4-4公开服务接收信息图 4-5 UDP客户端界面4-6 发送了消息的UDP客户端界面图 4-7 服务器开启了日志功能、保密服务:在客户端发送了停机密码后,可以控制服务器关机,但同时也会被服务器记录在案。以便今后管理员对攻击事件的追踪。图 4-8 服务器开启日志功能(2)、完成TCP/UDP协议客户端扫描程序可以扫描出公开和保密的全部端口号,确定全部公开的服务,甚少可以确定一种保密的服务。、扫描本机 1:查看哪些端口是开放的。图 4-9查看本机端口的开放情况2:采用传统单线程扫描熟知端口。图 4-10 传统顺序扫描的结果截图3:日志功能图 4-11 日志记录5:采用多线程扫描熟知端口图 4-12 多线程扫描的结果截图6:日志功能图 4-13 日志功能由以上截图对比可知,单线程扫描的速度慢,而多线程扫描则实现了高并发,扫描速度得到了大幅度的提升。但多线程扫描的难题是如何实现高并发却不会出现错误。因此,本人在扫描器中设定了两种模式,当扫描的端口范围较小时,建议使用单线程模式,这样可以避免多线程扫描端口范围较小时产生的错误,虽然单线程是顺序扫描而且一般服务器都有日志功能,但是扫描的范围较小时,比扫描端口范围大的更不容易被服务器察觉。当扫描端口范围较大时,建议采用多线程模式,首先是因为它的扫描速度比单线程模式快得多,每多创建一个线程扫描速度单线程快一倍,但线程并不是越多就越好,在这里我只创建了50个线程,扫描速度大约是原来单线程的50倍。其次,它所扫描的端口具有一定的随机性,如果采用传统的单线程模式顺序扫描并且扫描的端口范围大时,不仅扫描时间长,而且是顺序扫描,这样做是不明智的!(3)、可以扫描顾剑老师上课的服务器210.37.47.194,检查其安全情况。第一步:查看主机是否存活。Ping 210.37.47.194图 4-9 查看主机是否存活第二步:扫描主机的熟知端口号(01024)。图 4-10扫描主机的熟知端口号(01024)图 4-11 日志功能第三步:扫描主机的登记端口号(102549151)。图 4-12扫描主机的登记端口号(102549151)图 4-13 日志功能记录综上,服务器210.37.47.194提供了ftp服务和telnet服务。首先,telnet服务器容易遭受到拒绝服务攻击,另外telnet服务的开放使得为不合法用户开启了远程登录,并控制服务器,最后留下入侵后门。(4)、可以扫描 服务器,检查其安全情况。第一步:登陆网站,查看网址是否有效。图 4-14登陆网站,查看网址是否有效第二步:ping 域名以获得IP地址。图4-15 ping 域名以获得IP地址第三步:扫描服务器的熟知端口(01024)图 4-16扫描服务器的熟知端口(01024)给出一些防范和修改建议:linux的111端口可能存在安全隐患。建议关闭此端口。111端口是SUN公司的RPC(Remote Procedure Call,远程过程调用)服务所开放的端口,主要用于分布式系统中不同计算机的内部进程通信,RPC在多种网络服务中都是很重要的组件。常见的RPC服务有rpcmountd、NFS、rpcstatd、rpccsmd、rpcttybd、amd等等。在Microsoft的Windows中,同样也有RPC服务。如果可以不使用RPC服务的话,建议关闭此端口。第四步:查看该扫描记录是否已存于日志文件中图 4-17 日志功能第五步:扫描服务器的登记端口号(102549151)图 4-18扫描服务器的登记端口号(102549151)第六步:查看日志图 4-19 查看日志分析:45457端口开放,可能是某黑客留下的一个后门,建议系统管理员尽快关闭此端口。否则将会被某些黑客利用。5、个人感想与感悟通过本次课程设计使我更为深刻地认识到了编程的重要性,虽然老师让我们写的代码很多,但其实许多程序都是在老师的程序基础上修改的,所以我们真正写的代码其实只有扫描器的部分。但尽管如此,仍是把我更难住了,本来希望的设计目标是、所有程序都跨平台。、所有服务器都可以为多个客户端进行服务。、扫描程序实现多线程随机扫描。、所有程序都必须有日志记录。、将TCP扫描器设计为TCP connect 扫描和TCP SYN扫描两种模式。但最终只实现了两个半:扫描程序实现多线程随机扫描、所有程序都必须有日志记录、TCP扫描器设计为TCP connect 扫描。尽管没有达到自己预定目标,但通过本次课程设计仍是让我收获很大,并且更加深刻地认识到了自己的不足。今后,本人一定要在编程方面加强。否则,真的就是心有余而力不足啊。实验收获:TCP/IP协议是网络中使用最广泛的协议。Socket 套接口,最早出现在Berkeley Unix中,最初只支持TCPIP协议族和Unix协议,现在它已支持很多协议,是最重要的网络编程接口,特别是在Unix中,其核心直接支持socket 编程,几乎所有的网络应用程序都是用Socket API来实现的。WIN平台中,需要特别的处理并用动态库socket动态库DLL来实现。因此,需要在socket程序之外特别处理。面向连接的TCP通信:1,发起连接的为客户端Client ,接收连接的一方称为服务器端 Server。2,双方的通信一般分三步:建立连接、数据传送、释放连接。3,在传送过程中数据按顺序传送,很像电路交换,因此又称为“虚电路(VC,Virtual Circuit)服务”。4,这是一种使用者感觉可靠的服务,但建立连接和释放连接的开销很大。面向非连接的UDP通信:1,互为客户端和服务器端。任何一方都可随时向对方发送或接收数据。2,这是一种使用者感觉不可靠的服务,主要体现:报文丢失、重复或与发送顺序不一致等现象。3,使用者一定要编写高层协议来自行解决这些问题。4,缺点:对使用者要求高,优点:灵活、方便、效率很高(特别是对通信网络,要求低,效率高)两者比较:1,理论研究者为处理“不可靠”而做的选择,面向连接:可靠性由低层服务(网络)负责,面向非连接:可靠性由用户负责。2,能否实际通信,取决于实际的底层服务(网络)。面向非连接的数据报达到不了对方,面向连接的通信一样也不可能(这时基本是连接都建立不起来)。3,能否通信的“信息”:可靠性两者报告的方式不同。面向非连接需要使用者自己“感觉”,面向连接底层服务告诉使用者。得到“信息”的时间两者并不一定(取决于使用者 )。4,底层(网络)为了保证“可靠”需要随时进行通信(包含互发和记录信息),这样,开销十分庞大。特别是在使用长时间不进行实际通信时,更是极大的浪费。理论上的结论:1,使用者水平高、聪明时,使用面向非连接方式是明智的。2,为了效率,使用面向非连接方式是明智的。3,在可以容忍数据丢失的情况下,使用面向非连接方式是明智的。如ping。如视频/语音传送。4,如果非想随时了解线路是否可用,使用面向连接方式是明智的。附录(程序代码部分):附录一:(基于TCP通信的客户端与服务器)1. wqm_TCP_S.C 代码#include#include#include#include #include #define socklen_t int #pragma comment (lib, Ws2_32.lib)#define MyLogName Tcp_S.log#pragma pack(1) /结构在存储时按字节对齐#define ECom -100 /* 系统错误 */#define EPara1 -101 /* 第1个参数错误 */#define EPara2 -102 /* 第2个参数错误 */#define EMyRet -103 /* 自行退出错误 */#define MaxCliNo 5/* 打印系统错误号和错误信息后返回 */#define SysErr(S) perror(S);return(ECom);#define FFSTD fflush(stdout); /* 清除输出缓冲器. */* 打印地址信息 */#define PrAdrr(Addr) printf(%sn,#Addr); printf(family:%u n,Addr.sin_family); printf(addr :%08x=%sn,Addr.sin_addr.s_addr, inet_ntoa(Addr.sin_addr); printf(port :%u,%u n,Addr.sin_port, htons(Addr.sin_port);#define SERV_PORT 26 /* 服务器服务端口 */#define SA struct sockaddr /* socket地址缩写 */#define MAXLEN 4096 /* 最大缓冲长度 */char ServerIP20=127.0.0.1;FILE *fp;unsigned short SPort=SERV_PORT;unsigned short CPort;/*01*/int DoTCPServerDisp(void); /* 没有记录 的服务程序 */#define Demainint main(int argc,char *argv)int Ret=1;printf(/*TCP服务器*/n);printf( Server IP=%s Port=%dn,ServerIP,SPort);if(fp=fopen(Tcp_S.log,a)=NULL)printf(不能打开文件!n);exit(1);elseprintf(TCP服务器日志已打开!n); DoTCPServerDisp(); /* 记录接收发送数据的服务程序 */*01*/int DoTCPServerDisp() #ifdef _WIN32 WSADATA wsaData; #endif static SerNo=0; /*服务次数 */ int SockFd,sAccept; /* socket 句柄 */ int SockLen; /* socket 结构长度 */ int iSend; /* 发送信息长度 */ int iRecv; /* 接收信息长度 */ #define BufLen 1024 char SBufBufLen; /* 发送缓冲区 */ char RBufBufLen; /* 接收缓冲区 */ int SendLen; /* 发送数据长度 */ struct sockaddr_in ser,cli;if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) SysErr(WSAStartup() Failed!); if(SockFd=socket(AF_INET,SOCK_STREAM,0)=INVALID_SOCKET)SysErr(socket() Failed!); ser.sin_family=AF_INET; ser.sin_port=htons(SPort); ser.sin_addr.s_addr=inet_addr(ServerIP); printf(TCP Server Running at(Ip=%s Port=%d)n,ServerIP,SPort); if(bind(SockFd,(struct sockaddr*)&ser,sizeof(ser)=SOCKET_ERROR) SysErr(bind() Failed!); SockLen=sizeof(ser); if(listen(SockFd,MaxCliNo)-1) SysErr(listen() Failed!); SockLen=sizeof(cli);LoopAccept: /* 接受客户端连接请求 */ sAccept=accept(SockFd,(struct sockaddr*)&cli,&SockLen); if(sAccept=(-1)SysErr(accept() Failed!); printf(Accepted client IP:%s,prot:%dn, inet_ntoa(ser.sin_addr), ntohs(ser.sin_port);fprintf(fp,Accepted client IP:%s,prot:%dn, inet_ntoa(ser.sin_addr), ntohs(ser.sin_port);Loop: iRecv=recv(sAccept,RBuf,sizeof(RBuf),0); if(iRecv0) SysErr(receive error from client!n); else if(iRecv=0) printf( 一个客户端结束,现在开始为下一个客户服务!n);/可以顺序地为多个用户服务,但前提是前一个用户必须退出 goto LoopAccept; /* 服务处理 */ RBufiRecv=0; sprintf(SBuf,%s(%d:%d)SerNo=%d R(%s:%d), RBuf,strlen(RBuf),iRecv,+SerNo, inet_ntoa(cli.sin_addr),ntohs(cli.sin_port); fprintf(fp,%s(%d:%d)SerNo=%d R(%s:%d), RBuf,strlen(RBuf),iRecv,+SerNo, inet_ntoa(cli.sin_addr),ntohs(cli.sin_port); iSend=send(sAccept,SBuf,strlen(SBuf),0); if(iSend-1)SysErr(send() Failed:%dn); else if(iSend=0) printf(iSend=0 Errorr? n);goto Loop; fprintf(fp,send %s(%d) OKn,SBuf,iSend); goto Loop; LEnd: closesocket(SockFd); WSACleanup(); return(0);/* end 01 int DoTCPServer() */2. wqm_TCP_C.C 代码#include#include#include#include #include #define socklen_t int /*Gujians programs need the definition */#pragma comment (lib, Ws2_32.lib)#pragma pack(1) /结构在存储时按字节对齐#define ECom -100 /* 系统错误 */#define EPara1 -101 /* 第1个参数错误 */#define EPara2 -102 /* 第2个参数错误 */#define EMyRet -103 /* 自行退出错误 */* 打印系统错误号和错误信息后返回 */#define SysErr(S) perror(S);return(ECom);#define FFSTD fflush(stdout); /* 清除输出缓冲器. */* 打印地址信息 */#define PrAdrr(Addr) printf(%sn,#Addr); printf(family:%u n,Addr.sin_family); printf(addr :%08x=%sn,Addr.sin_addr.s_addr, inet_ntoa(Addr.sin_addr); printf(port :%u,%u n,Addr.sin_port, htons(Addr.sin_port);#define SERV_PORT 26 /* 服务器服务端口 */#define SA struct sockaddr /* socket地址缩写 */#define MAXLEN 4096 /* 最大缓冲长度 */char ServerIP20=127.0.0.1;unsigned short SPort=SERV_PORT;unsigned short CPort;/*c01*/int DoTCPClient(void); /* 没有记录程序的客户端程序*/*c02*/int DoTCPCliWri(void); /* 有记录程序的客户端程序*/*02*/int DoTCPServerWrite(void); /* 记录接收发送数据的服务程序 */#define Demainint main(int argc,char *argv)int Ret=1; #ifdef Demainprintf(/* TCP客户端 */n);printf( Server IP=%s Port=%dn,ServerIP,SPort);#endif DoTCPClient(); /* 没有记录程序的客户端程序*/ DoTCPCliWri(); /* 有记录程序的客户端程序*/#define EndStr RUN /* 服务器停机密码*/#define DeDoTCPClient/*c01*/int DoTCPClient() /* 没有记录程序的客户端程序*/ #ifdef _WIN32 WSADATA wsaData; #endif int SNo=0; int SockFd; /* socket 句柄 */ int iSend; /* 发送信息长度 */ int iRecv; /* 接收信息长度 */ #define BufLen 1024 char SBufBufLen; /* 发送缓冲区 */ char RBufBufLen; /* 接收缓冲区 */ int SendLen; /* 发送数据长度 */ struct sockaddr_in ser; char C=O; memset(RBuf,0,sizeof(RBuf); #ifdef _WIN32 if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0) printf(Failed to load Winsock!n); return -1; #endif ser.sin_family=AF_INET; ser.sin_port=htons(SPort); ser.sin_addr.s_addr=inet_addr(ServerIP); if(SockFd=socket(AF_INET,SOCK_STREAM,0)=INVALID_SOCKET) SysErr(socket() Failed!); if(connect(SockFd,(struct sockaddr*)&ser,sizeof(ser)=INVALID_SOCKET) SysErr(connect() Failed);Loop: printf( 请输入你想说的话:); scanf(%s,SBuf); SendLen=strlen(SBuf); sprintf(&SBufSendLen,Client:%d,SNo+); #ifdef DeDoTCPClient printf(SBuf=%s:%d EndStr=%s:%dn, SBuf,SendLen,EndStr,strlen(EndStr); #endif if(memcmp(SBuf,EndStr,SendLen)=0) printf( 现在一个客户端退出服务!n);goto LEnd; SendLen=strlen(SBuf); iSend=send(SockFd,SBuf,SendLen,0); if(iSend-1) perror(send() Failed); printf( Send OK(%d:%d)n,iSend,SendLen); iRecv=recv(SockFd,RBuf,sizeof(RBuf),0); if(iRecv=0) printf(iRecv =0n); goto LEnd; else if(iRecv=SOCKET_ERROR) perror(recv() Failed); return(0); printf(R %s(%d)n,RBuf,iRecv); goto Loop;LEnd: closesocket(SockFd); WSACleanup();/* end int doTCPClient() */附录二:(基于UDP通信的客户端与服务器)1. wqm_UDP_S.C 代码#include#include#include#include#include /* _getch() 需要的头文件*/#include #include #include #include #define socklen_t int /*Gujians programs need the definition */#pragma comment (lib, Ws2_32.lib)#pragma pack(1) /结构在存储时按字节对齐/* Begin 以下定义用于记录发送和接收数据 */ /* Wins 用 */ #define WQM_Open (fd =_open(MyLogName,_O_BINARY|_O_WRONLY|_O_CREAT|_O_TRUNC, _S_IREAD | _S_IWRITE)0) #define WQM_OpAP (fd =_open(MyLogName,_O_BINARY|_O_WRONLY|_O_CREAT, _S_IREAD | _S_IWRITE)0) #define WQM_Write(Buf,Len) (_write(fd,Buf,Len)!=Len #define WQM_WLine (_write(fd,SLine,2)!=2 #define WQM_Close _close(fd); #define WQM_GoHead if(_lseek(fd,0L,SEEK_END)0) SysErr(lseek);#include#include/* End 以下定义用于记录发送和接收数据 */#define ECom -100 /* 系统错误 */#define EPara1 -101 /* 第1个参数错误 */#define EPara2 -102 /* 第2个参数错误 */#define EMyRet -103 /* 自行退出错误 */* 打印系统错误号和错误信息后返回 */#define SysErr(S) perror(S);return(ECom);#define FFSTD fflush(stdout);
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 图纸下载 > CAD图纸下载


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!