




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、一本实验目的及要求:1 掌握TCP/IP体系结构中端口、套接字、TCP协议概念。理解什么是SAP、端口的范围划分、套接字的组成等概念,掌握TCP传输模式和netstat命令的用途;2 掌握TCP SOCKET的ServerSocket和Socket;学习为TCP服务的 Socket和ServerSocket类的使用,掌握TCP连接的方法,服务器接收客户端连接请求的方法,创建输入/输出流的方法,传输数据的方法,以及关闭流和套接字,注意可能会出现的异常操作;3 理解进程和线程的概念,掌握TCP SOCKET技术中多线程技术,理解JAVA中的动态数组的内容。4 实验报告内容应包括,本实验的第三、四、
2、五部分的答案,以及第六部分的程序后要求。二、基础知识1. TCP协议TCP是一种面向连接的、可靠的、基于字节流的运输层(Transport layer)通信协议。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,UDP是同一层内另一个重要的传输协议。TCP所提供服务的主要特点:面向连接的传输;端到端的通信;高可靠性,确保传输数据的正确性,不出现丢失或乱序;全双工方式传输;采用字节流方式,即以字节为单位传输字节序列;紧急数据传送功能TCP支持的服务:文件传送File Transfer;远程登录Remote login;计算机邮件Mail;网络文件系统(NFS);远程打印(Remot
3、e printing);远程执行(Remote execution);名字服务器(Name servers);终端服务器(Terminal servers)。 2. 端口TCP/IP协议中提出了端口(port)的概念,用于标识网络主机上通信的软件进程。 端口实际上是一个抽象的软件结构(包括一些数据结构和I/O缓冲区)。应用程序(即进程)通过系统调用与某端口建立关联(binding)后,传输层传给该端口的数据都被相应的应用进程所接收。端口又是在网络体系结构中应用进程访问传输服务的入口点SAP(Service Access Point服务访问点)。在TCP/IP体系中,用于存储端口号长度为16bi
4、t ,取值范围065535,它用于存储本地软件进程,所以仅具有本地意义。通常,端口分为:熟知端口,取值范围01023,为常用应用进程指定的固定值;一般端口,取值范围102449151,供一般程序使用;动态端口:4915265535供某些默认服务使用,如表1所示。表1 常用进程和熟知端口echo7验证2台计算机连接有效性daytime13服务器当前时间文本描述ftp20/2121用于命令,20用户数据telnet23远程登录smtp25邮件发送whois43网络管理的目录服务dns53域名解析tftp69小文件传输finger79主机用户信息http80HTTPpop3110邮局协议nntp11
5、9网络新闻传输协议, 发布Usenet新闻snmp161网络管理协议rip520路由协议 3. 套接字套接字Socket原意是 “插座”,简单的说就是参与通信两方的一种约定,用套接字中的相关函数来完成通信过程。为了区分不同应用程序进程间的网络通信和连接,主要使用3个参数:通信的目的IP地址、使用的传输层协议(TCP或UDP)和使用的端口号,通过将这3个参数结合起来,与一个Socket绑定,应用层就可以和传输层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。通常的表示方式为:SOCKET=(传输协议,IP,Port)。 4 . NetstatNetStat是DO
6、S命令,是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息.Netstat用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。可以通过执行Netstat /help获得该应用程序选项的相关帮助。在Java语言中,实现TCP 套接字中有两个基础类,分别为:l Socket类: 建立一个客户端标识l ServerSocket类: 建立一个服务器端标识 5. ServerSocket该类实现服务器socket,一个服务器socket等待网络上的连接请求。通常操作都是基于这个请求,并且会返回一个结果
7、给请求连接者,其类描述如图2所示。图2 ServerSocket类描述ServerSocket构造方法有:ServerSocket() 创建一个空的服务端socket;ServerSocket(int port) 在指定端口创建一个服务端socket,;ServerSocket(int port, int backlog) 在指定端口创建一个服务端socket和日志;ServerSocket(int port, int backlog, InetAddress bindAddr) 在指定端口和地址上创建一个服务端socke
8、t和日志。 6. Socket该类实现一个客户端socket,这个socket表示在通信的两台设备之间的端点,其类描述如图3所示。图3 Socket类描述Socket构造方法有:Socket() 创建一个空的客户端socket;Socket(InetAddress address, int port) 创建一个连接指定远程地址和端口的客户端socket;Socket(InetAddress address, int port, InetAddress localAddr, int localPort) 在本地指定地址和端口,创建一个连
9、接指定远程地址和端口的客户端socket;Socket(String host, int port) 创建一个连接指定主机名称和端口的客户端socket;Socket(String host, int port, InetAddress localAddr, int localPort) 在本地指定地址和端口,创建一个连接指定远程主机名称和端口的客户端socket。基本工作原理,如图4所示。1 启动服务器端ServerSocket,监听指定端口;2 启动客户端Socket,连接服务器端Socket;3 服务器端Accept确认连接,建
10、立通信通道;4 建立输入和输出流,进行通信;5 通信完毕,关闭Socket连接。7. 多线程(Thread)每个正在系统上运行的程序都是一个进程。每个进程包含一到多个线程。进程也可能是整个程序或者是部分程序的动态执行。线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行。也可以把它理解为代码运行的上下文。所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务。Java里面有2个方法实现多线程,不论哪种方法都需要覆盖public void run()方法1 继承 Thread类,比如class MyThread extends Thread public void run() /
11、 这里写上线程的内容 public static void main(String args) / 使用这个方法启动一个线程 new MyThread().start(); 2 实现 Runnable接口class MyThread implements Runnable public void run() / 这里写上线程的内容 public static void main(String args) / 使用这个方法启动一个线程 new Thread(new MyThread().start(); 一般鼓励使用第二种方法,因为Java里面只允许单一继承,但允许实现多个接口。第二个方法更加灵
12、活。三类及方法:1. ServerSocket常用方法 Socketaccept() 接受客户端的连接请求; voidbind(SocketAddress endpoint) 绑定到指定的地址和端口; voidclose() 关闭该ServerSocket; InetAddressgetInetAddress() 获得该ServerSocket的本地地址; intgetLocalPort() 获得本地监听端口; intgetReceiveBufferSize() 获得接收缓存尺寸; intgetSoTimeout(
13、) 获得数据包超时时间; booleanisClosed()判断ServerSocket是否关闭; voidsetReceiveBufferSize(int size)设置接收缓存尺寸; voidsetSoTimeout(int timeout) 以毫秒设置数据包超时时间; StringtoString() 将地址和端口作为字符串返回。2. Socket常用方法 voidbind(SocketAddress bindpoint) 绑定socket在本地; voidclose() 关闭该socket;
14、60;voidconnect(SocketAddress endpoint) 连接该socket到服务器上; voidconnect(SocketAddress endpoint, int timeout) 连接该socket到服务器并设置超时时间; InetAddressgetInetAddress() 获得该socket连接的地址; InputStreamgetInputStream() 获得该 socket的输入流; InetAddressgetLocalAddress() 获得该socket的本地地址; i
15、ntgetLocalPort()获得该socket的本地端口; OutputStreamgetOutputStream()获得该 socket的输出流; intgetPort()获得该 socket的远端端口; intgetReceiveBufferSize() 获得该Socket的接收缓存容量; intgetSendBufferSize()获得该Socket的发送缓存容量; intgetSoTimeout() 获得超时时间; booleanisClosed() 判断该socket是否关闭; booleanisConnect
16、ed() 判断该socket是否连接; voidsetKeepAlive(boolean on) 设置该socket的连接状态; voidsetReceiveBufferSize(int size) 设置接收缓存容量; voidsetSendBufferSize(int size) 设置发送缓存容量; voidsetSoTimeout(int timeout) 设置毫秒级的超时时间; StringtoString() 将该socket转换为字符串输出。三、基础概念填空1. TCP是(一种面向连接的、可靠的
17、、基于字节流的运输层(Transport layer)通信协议 ), UDP是( TCP/IP 参考模型中传输层的无连接协议 ,提供面向事务的、简单的、不可靠数据传送服务 )。2. 端口是(网络体系结构中应用层与传输层之间的通信协议接口 ),由( 16 )bit构成,表示范围( 065535 ),其代表了( 存储本地软件)进程,且只具备本地意义。3. 套接字是(参与通信两方的一种约定,用套接字中的相关函数来完成通信过程 ),其三个构成部分是( 通信的目的IP地址 )、( 使用的传输层协议(TCP或UDP) )和(使用的端口号 )。4. NetStat是(DOS命令,是一个监控TCP/IP网络的
18、非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息 ),要查看有效连接信息使用的参数是( -a ),要查看所有的连接信息使用的参数是( -n )。当发现连接的状态是Listening表示( 某端口 是个开放的TCP端口,正处于监听状态,等待远程用户的连接 ),Established表示(表示已建立通信连接,两台机器正在交换数据 )。5. 在JAVA中TCP的套接字类是( Socket )和(ServerSocket )。ServerSocket类的accept的作用是( 实现与客户端的连接,完成TCP连接的三次握手 ),Socket类获得输入流的方法是(Input
19、Stream getInputStream() ),获得输出流的方法是(OutputStream getOutputStream() ).4、 程序填空1. 客户端连接服务器端import java.io.* /引用输入与输出类库import .* /引用网络类库public class exp_5_1 public static void main(String args) String hostName = "" int port = 80; Socket cs = null; try cs = new Socket (hostName, port); System.o
20、ut.println("连接"+hostName+"的端口"+port+"成功"); System.out.println("对方主机" + cs.getInetAddress() + ":对方端口" + cs.getPort(); System.out.println("本地主机" + cs.getLocalAddress() + ":本地端口" + cs.getLocalPort(); Cs. close (); catch(Exception e)
21、System.err.println("无法连接指定服务"); 2. 客户端连接服务器端,并获得输入与输出流import java.io.*;import .*;public class exp_5_3 public static void main(String args) throws IOException Socket cs = null; DataOutputStream os = null; DataInputStream is = null; try/建立socket连接 cs = new Socket ("localhost", 8000
22、);/发出连接请求 is = new DataInputStream(cs. getInputstream (); os = new DataOutputStream(cs. getOutputstream (); catch(UnknownHostException e) System.err.println("不可识别的主机"); System.exit(0); catch(IOException e) System.err.println("无法链接到服务器的8000端口"); System.exit(0); DataInputStream std
23、In = new DataInputStream(System.in); System.out.print("请输入你的用户名:"); String username = stdIn.readLine(); String fromServer, fromUser; while(fromServer = is.readUTF() != null) System.out.println("Server:" + fromServer); if(fromServer.equals("bye") break; System.out.print(
24、"Client:"); fromUser = stdIn.readLine(); os.writeUTF(username + "#" +fromUser); Os. flush (); os.close(); is.close(); stdIn.close(); cs.close(); 3. 服务器端程序import java.io.*;import .*;public class exp_5_4/TCP通信,作为服务器 public static void main(String args) throws IOException ServerSock
25、et ss = null; try ss = new ServerSocket (8000); System.out.println("服务器开始监听8000端口的连接请求"); catch(IOException e) System.err.println("8000端口不能使用"); System.exit(1); Socket cs= null; try cs = ss. accept (); catch(IOException e) System.err.println("接受客户机端连接失败"); System.exit(1
26、); DataOutputStream os = new DataOutputStream(cs.getOutputStream(); DataInputStream is = new DataInputStream(cs. getInputStream() ); String inputStr, outputStr; /输出操作 os.writeUTF("Welcome to My Chat Server"); os.flush();/立即将数据从输出缓存提交给网络发送 DataInputStream stdIn = new DataInputStream( System
27、.in ); /获得键盘输入流 /输入操作 while(inputStr= is. readUTF() != null) /接受网络数据 System.out.println("Customer:" + inputStr); System.out.print("Server:"); outputStr = stdIn.readLine(); /接受键盘输入 Os. writeUTF (outputStr); /向网络发送数据 os.flush(); if(outputStr.equals("bye") break; os.close(
28、);/流关闭 is.close(); cs.close();/套接字关闭 ss.close(); 五、实验内容1在Windows下使用netstat命令,查看本地计算机开放端口。获得/help,分别测试-s -e r -a n及其组合。2. 对指定IP范围内主机上指定PORT范围进行连接测试。 import .*; (2分)import java.io.*;class myJavapublic static void main(String args)String host = "222.24.16." (2分) String host_ip = null;Socket c
29、s = null;for(int i=1; i<17; i+) (2分)host_ip = host + i;for(int j=0; j<65536; j+) trycs = new Socket(host_ip, j); (2分)System.out.println(host_ip + " : " + j);catch(Exception e) (2分)System.err.println();报告内容:运行结果,获得探测范围中对主机开放端口数进行统计,并得到所消耗的总时间。利用RandomAccessFile将探测结果保存在文件中(IP地址和开放的端口号)
30、2简单的单线程,一问一答式通信的TCP Server和TCP Client,注意在编译源代码时有个提示“某API已经过时”,找到该API类或者方法。在运行程序时,注意通信双方是否随时输入,如果不能,考虑可能是什么原因造成的。/服务器端import java.io.*;import .*;public class SimpleServer/位置一public static void main(String args)/TCP通信,作为服务器ServerSocket serverSocket = null; /位置二/首先建立服务器try/端口号唯一标是本进程 /位置三serverSocket =
31、 new ServerSocket(10); /修改10为本地TCP已被占用的端口,或超过065535的端口,观察结果System.out.println("Server is Listening on Port 10 Now");catch(IOException e)System.err.println("Can't listen on port 10");System.exit(1);/接受客户端连接Socket clientSocket = null;tryclientSocket = serverSocket.accept(); /co
32、nnectcatch(IOException e)System.err.println("Accept failed");System.exit(1);tryPrintStream out = new PrintStream(new BufferedOutputStream(clientSocket.getOutputStream(), 1024) ,false);DataInputStream in = new DataInputStream(new BufferedInputStream(clientSocket.getInputStream();String inpu
33、tLine, outputLine;/输出操作out.println("Welcome to My Chat Server");out.flush();/立即将数据从输出缓存提交给网络发送 /接收键盘输入 DataInputStream stdIn = new DataInputStream(System.in);/输入操作while(inputLine = in.readLine() != null) /接受网络数据System.out.println("Customer:" + inputLine);System.out.print("Se
34、rver:");outputLine = stdIn.readLine(); /接受键盘输入/System.out.println("Server:" + outputLine);out.println(outputLine); /向网络发送数据out.flush();if(outputLine.equals("bye") break;out.close();/流关闭in.close();clientSocket.close();/套接字关闭serverSocket.close();catch(IOException e)System.err.
35、println("Protocol Stream Error"); /客户端import java.io.*;import .*;public class MyClientpublic static void main(String args) throws IOExceptionSocket comSocket = null;PrintStream out = null;DataInputStream in = null;try/建立socket连接comSocket = new Socket("localhost", 1080);/相指定服务器的端口
36、发出连接请求,注意服务器开放的TCP端口号 /分别对应服务器端的O/I流in = new DataInputStream(comSocket.getInputStream();out = new PrintStream(comSocket.getOutputStream();catch(UnknownHostException e)System.err.println("Can't find the Server host");System.exit(0);catch(IOException e)System.err.println("Can't
37、get I/O for the Connection");System.exit(0);DataInputStream stdIn = new DataInputStream(System.in);String fromServer, fromUser;while(fromServer = in.readLine() != null)System.out.println("Server:" + fromServer);if(fromServer.equals("bye") break;fromUser = stdIn.readLine();if
38、(fromUser != null)System.out.println("Client:" + fromUser);out.println(fromUser);out.close();in.close();stdIn.close();comSocket.close();注意:将位置二的语句分别放置到位置一和位置三,编译看会出现什么问题,为什么会出现问题,该如何解决。答:不能。只能每次等对方输入完才行,可能是因程序运行时占用同一通道,只能等对方不占用通道时才能执行。将位置二的语句放到位置一时,位置三会报错,因为此时serverSocket的作用范围不在位置三内,应将serv
39、erSocket用static修饰;将位置二的语句放到位置三时,调用accept()方法的serverSocket会报错,因为此时serverSocket的作用范围被缩小在第一个try catch块中,应该在第一个try catch块的外面进行serverSocket的初始化。4以下代码是个非常经典的用户自定义一问一答协议,在这里只需要修改服务器端程序即可,添加了GreetingProtocol.java(自定义协议),调试并修改协议使程序可以正常运行。/服务器端import java.io.*;import .*;public class MyServerpublic static void
40、 main(String args)/TCP通信,作为服务器ServerSocket serverSocket = null; /首先建立服务器tryserverSocket = new ServerSocket(1080);System.out.println("Server is Listening Now");catch(IOException e)System.err.println("Can't listen on port");System.exit(1);/接受客户端连接Socket clientSocket = null;tryc
41、lientSocket = serverSocket.accept(); /connectcatch(IOException e)System.err.println("Accept failed");System.exit(1);tryPrintStream out = new PrintStream(new BufferedOutputStream(clientSocket.getOutputStream(), 1024) ,false);DataInputStream in = new DataInputStream(new BufferedInputStream(c
42、lientSocket.getInputStream();String inputLine, outputLine; /自定义协议GreetingProtocol greeting = new GreetingProtocol();outputLine = cessInput(null);/输出操作out.println("Welcome to My Chat Server");out.flush();/立即将数据从输出缓存提交给网络发送/输入操作while(inputLine = in.readLine() != null)System.out.p
43、rintln(outputLine); /协议处理信息 outputLine = cessInput(inputLine); out.println(outputLine);out.flush();if(outputLine.equals("bye") break;out.close();/流关闭in.close();clientSocket.close();/套接字关闭serverSocket.close();catch(IOException e)System.err.println("Protocol Stream Error&quo
44、t;); /自定义协议public class GreetingProtocolprivate static final int WAITING = 0;private static final int SENDKNOCK = 1;private static final int SENDCLUE = 2;private static final int ANOTHER = 3;private static final int NUMJOKES = 5;private int state = WAITING;private int currentJoke = 0;private String
45、clues = "Turnip", "Little Old Lady", "Atch", "Lamp", "Godness"private String answers = "Turnip the heat, it's cold in here!","I did not know you could come!","Bless you","Lamp is bright","Godness is ha
46、ppy"public String processInput(String theInput)String theOutput = null;if(state = WAITING)theOutput = "Knock! Knock!."state = SENDKNOCK;else if( state = SENDKNOCK)if(theInput.equalsIgnoreCase("Who's there?")theOutput = cluescurrentJoke;state = SENDCLUE;elsetheOutput = &q
47、uot;You are supposed to say " Who's there? "! Try again."else if( state = SENDCLUE)if(theInput.equalsIgnoreCase(cluescurrentJoke + "Who?")theOutput = answerscurrentJoke + "Want another?(y/n)"state = ANOTHER;elsetheOutput = "You are supposed to say "&q
48、uot; + cluescurrentJoke + "Who? "! Try again. Knock! Knock!"state = SENDKNOCK;else if( state = ANOTHER)if(theInput.equalsIgnoreCase("y")theOutput = "Knock! Knock!"if(currentJoke = (NUMJOKES - 1)currentJoke = 0;elsecurrentJoke +;state = SENDKNOCK;elsetheOutput = &qu
49、ot;bye"state = WAITING;return theOutput;3探测目标计算机开放的TCP 端口import java.io.*;import .*;public class ScanPortpublic static void main(String args) throws IOExceptionSocket comSocket = null;for(int i=0;i<1024; i+)try/建立socket连接comSocket = new Socket("localhost", i);/发出连接请求System.out.prin
50、tln("Can get I/O for the Connection, Port:" + i);catch(UnknownHostException e)System.err.println("Can't find the Server host");/System.exit(0);catch(IOException e)System.err.println("Can't get I/O for the Connection, Port:" + i);/System.exit(0);trycomSocket.clos
51、e();catch(Exception e)思考:是否可以探测目标计算机的UDP端口4. TCP传输文件/采用TCP进行通讯,需要服务器和客户端两个部分,因此程序包含SendFileServer.java和SendFileClient.java两个部分。两个文件的IP,端口都在程序中指定, 传输的文件路径也在程序中指定/SendFileServer.javaimport java.io.FileInputStream;import java.io.IOException;import java.io.OutputStream;import .ServerSocket;import .Socke
52、t;/* * 用TCP进行文件传输 * 此文件为服务器文件 * 当接受到客户端的请求之后,先向其传输文件名 * 当客户端接受完毕之后,向客户端传输文件 * */public class SendFileServer implements Runnable/ 服务器监听端口private static final int MONITORPORT = 12345;private Socket s ;public SendFileServer(Socket s) super();this.s = s;public static void server()try / 创建服务器socketServerSocket ss = new ServerSocket(MONITORPORT);while(true)/ 接收到一个客户端连接之后,创建一个新的线程进行服务/ 并将联通的sock
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
评论
0/150
提交评论