




已阅读5页,还剩18页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
网络编程1. 网络编程引言回顾单机的IO传输,如何多个PC之间数据传输?利用网络在多个PC之间数据传输。就是Socket编程。什么是计算机网络是指特定的物理线路,将分散,独立的计算机或者相关设备连接起来,并通过共用的协议进行数据传送,实现资源共享.1.1. IP地址当一台计算机要与另一台计算机通信时,需要知道另外一台计算机的地址.互联网协议(Internet Protocol ,IP)可以用来唯一的标识互联网上的计算机.IP地址由4段用点隔开的0255的十进制数组成例如,52 .IP地址是网络中用于区分不同计算机的数字标识,由32个二进制位组成.并将其分成4组,每组8位.32位的IP地址由于用二进制表示不便于记忆,因而采用称为点分十进制的方法表示。例如: 目前IP协议的版本号是4(IPv4)下一个版本是IPv6。IPv4采用32位(bit)地址长度,只有大约43亿个地址(232)。 IPv6具有更大的地址空间,IPv6中IP地址的长度为128位,即最大地址个数为2128。 IP地址就好像电话号码:有了某人的电话号码,你就能与他通话了。同样,有了某台主机的IP地址,你就能与这台主机通信了。1.2. 域名由于ip地址是数字,不容易记忆.所以就将他们映射为域名(domain name)例如: 在互联网中有叫做域名服务器(Domain Name Server DNS)的服务器,它可以把这个域名转换为Ip地址.然后根据这个Ip地址实现通信.在命令行中使用:ipconfig可以查询自己的IP.ping 尝试连接某ip地址特殊Ip地址 本地回路地址主机名:localhost,ping这个地址可以测试网卡是否可用1.3. 端口号计算机端口(port) 是计算机与外界通信交流的出口。计算机通过端口区分Internet的各种服务.计算机上的每一个程序都会对应一个端口号.例如使用计算机可以进行E-Mail(邮件) WWW(浏览器) FTP(文件传输)操作. 这些程序都需要通过互联网进行数据的传输.计算机是通过端口进行的判断数据的归属,不同的程序有不同的端口.端口是有范围限制的,端口号只有整数0-65535。(1)公认端口(wellkonwn ports) 范围是0-1023 系统保留端口。(2)注册端口(registered ports) 范围1024-49151松散绑定一些服务,虽然有一些服务绑定这些端口,这些端口还可以应用于其他服务。(3)动态/私有端口(dynamic and/)范围49152-65535 动态分配是指当一个系统进程或应用程序进程需要网络通信时,它向主机申请一个端口,主机从可用的端口号中分配 一个供它使用。当这个进程关闭时,同时也就释放了所占用的端口号。所以, 如果程序中需要指定端口,那么尽量使用1024以上的, 1024以下基本都被系统程序占用了.互联网协议是在互联网中从一台计算机向另一台计算机传输数据的规则,数据是以包的形式封装的。有两个和互联网一起使用的协议是UDP和TCP.1.4. UDPUser datagram protocol (用户数据报协议)特点:无连接、不可靠、速度快将数据及源和目的封装成数据包中,不需要建立连接。每个数据报的大小在限制在64k内例如: UDP协议不能保证传输没有丢失视频通话,即时通信,IP电话 (VoIP)电话1.5. TCPTransmission control protocol (传输控制协议)特点:面向连接、可靠、效率稍低通过三次握手,建立连接,形成传输数据的通道。在连接中进行大数据量传输例如: 因为Tcp协议能够发现丢失的传输数据并重新发送,所以适合文件传输,接收邮件2. Java程序设计的网络编程Java是通过Socket机制实现网络间的数据通信的.Socket就是为网络服务提供的一种机制。通信的两端都有Socket。网络通信其实就是Socket间的通信。数据在两个Socket间通过IO传输。2.1. InetAddress既然要使用网络编程,那么Ip地址是需要经常使用的,Java提供了一个类来表示IP地址。.InetAddress类是Java的IP地址封装类,它不需要用户了解如何实现IP地址的细节。InetAddress类没有构造方法,要创建该类的实例对象,可以通过该类的静态方法获得该对象方法:public static InetAddress getLocalHost() 获得本机的InetAddress对象,当查找不到本地机器的地址 时,发生UnknownHostException异常。 public static InetAddress getByName (String host) 该方法获得由host指定的InetAddress对象,host是计算机的域名(例如 ),其作用跟IP地址一样,只不过域名标识计算机比IP标识计算机更易于记忆。如果找不到主机会发生UnknownHostException异常。 public static InetAddress getAllByName(String host) 使用getAllByName方法可以从DNS上得到域名对应的所有的IP.这个方法返回一个InetAddress类型的数组出错了同样会抛出UnknownException异常测试方法:2.1.1. 获取本机IP地址/ 获取本机private static void tsstLocalHost() throws UnknownHostException / 获取本机Ip地址InetAddress localHost = InetAddress.getLocalHost();/ 通过InetAddress对象,方法实现操作System.out.println(localHost);/ 获取Ip 十进制String hostAddress = localHost.getHostAddress();System.out.println(hostAddress);/ 获取主机名String hostName = localHost.getHostName();System.out.println(hostName);/ ip字节表示形式byte address = localHost.getAddress();System.out.println(Arrays.toString(address);/ Java 的字节数是有符号的,能存-128 127.System.out.println(Integer.toBinaryString(192);System.out.println(Integer.toBinaryString(-64);2.1.2. 根据域名获取Ip获取www.baidu.con 域名的Ip地址。获取 域名的所有IP地址。/ 获取baidu的ip地址private static void testBaidu() throws UnknownHostException / 获取 Ip地址String host = ;/ InetAddress byName = InetAddress.getByName(host);/ String hostAddress = byName.getHostAddress();/ System.out.println(hostAddress); / 25/ 获取InetAddress allBynameBaidu = InetAddress.getAllByName(host);for (InetAddress i : allBynameBaidu) System.out.println(i.getHostAddress();2.2. Java中的UDP需要学习使用的类:DatagramSocketDatagramPacket需要建立发送端,接收端。建立数据包。将数据存储在数据包中.调用Socket的发送接收方法。关闭Socket。发送端与接收端是两个独立的运行程序。2.2.1. UDP发送第一步:创建Socket需要创建Socket, 发送端不需要指定ip地址和端口, 使用本机地址发送, 会自动找到未使用的端口。需要使用DatagramSocket此类表示用来发送和接收数据报包的套接字。java.lang.Object .DatagramSocket可以通过构造函数创建该Socket对象DatagramSocket socket = new DatagramSocket();第二步:创建数据包发送时需要创建数据包如何创建数据包?使用DatagramPacketjava.lang.Object .DatagramPacket 此类表示数据报包。 创建数据包时需要通过构造函数指定发送的数据(字节数组),数据长度(数组长度),接受方的IP地址(InteAddress类),接受方端口号(port)。构造函数:DatagramPacket(byte buf, int length, InetAddress address, int port) 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。第三步:发送数据有了Socket 有了数据,如何发送数据包?使用Socket的send方法将数据包发送出去void send(DatagramPacket p) 从此套接字发送数据报包。第四步:关闭Socket使用Socket的close方法关闭。void close() 关闭此数据报套接字。注意: 在发送端,要在数据包对象中明确目的地IP及端口。2.2.2. UDP接收第一步:需要创建Socket,接收时必须指定端口号.DatagramSocket socket = new DatagramSocket(8888);第二步:创建数据包,接收时也需要创建数据包, 用来存储数据. 需要一个字节数组.DatagramPacket packet = new DatagramPacket(new byte1024, 1024);接收数据第三步:接收数据使用DatagramSocket 的receive方法接收数据.该方法需要指定数据包.socket.receive(packet);第四步: 从数据包中获取数据byte data = packet.getData();第五步:获取数据长度int len = packet.getLength();第六步:获取发送端ip地址packet.getInetAddress().getHostAddress();第七步:获取发送端端口号packet.getPort();第八步:关闭socketsocket.close();注意: 在接收端,要指定监听的端口。2.2.3. 案例一:发送数据:使用UDP将一串数据发送出去,并使用UDP接收.要求获取到发送者的Ip地址端口号.并将信息显示出来.public class UDPSend public static void main(String args) throws SocketException,UnknownHostException, IOException System.out.println(UDP发送端启动,准备发送数据);/ 创建Socket,DatagramSocket socket = new DatagramSocket();/ 创建数据包String data = 你好我是UDP;InetAddress ip = InetAddress.getByName(52);DatagramPacket packet = new DatagramPacket(data.getBytes(),data.getBytes().length, ip, 50000);/ 发送数据socket.send(packet);/ 关闭socketsocket.close();System.out.println(udp发送端数据发送完毕);接收数据public class UdpReceive public static void main(String args) throws SocketException, IOException System.out.println(这是Udp接收端,已经启动,等待接收);/ 创建Socket 接收端必须指定端口号DatagramSocket socket = new DatagramSocket(50000);/ 创建接受的数据包byte byt = new byte1024;DatagramPacket packet = new DatagramPacket(byt, byt.length);/ 接收socket.receive(packet);/ 获取发送方ipInetAddress address = packet.getAddress();String hostAddress = address.getHostAddress();/ 获取发送方端口号int port = packet.getPort();/ 获取数据byte data = packet.getData();/ 获取数据长度int dataLen = packet.getLength();System.out.println(IP: + hostAddress + 端口号: + port + 发送了: + new String(data, 0, dataLen);socket.close();System.out.println(接收端接受完毕.);2.2.4. 异常处理:发送端:public class UDPSend public static void main(String args) System.out.println(UDP发送端启动,准备发送数据);/ 创建Socket,DatagramSocket socket = null;try socket = new DatagramSocket();/ 创建数据包String data = 你好我是UDP;InetAddress ip = InetAddress.getByName(55);DatagramPacket packet = new DatagramPacket(data.getBytes(),data.getBytes().length, ip, 50000);/ 发送数据socket.send(packet); catch (IOException e) e.printStackTrace(); finally / 关闭socketsocket.close();System.out.println(udp发送端数据发送完毕);接收端:public class UdpReceive public static void main(String args) System.out.println(这是Udp接收端,已经启动,等待接收);/ 创建Socket 接收端必须指定端口号DatagramSocket socket = null;try socket = new DatagramSocket(50000);/ 创建接受的数据包byte byt = new byte1024;DatagramPacket packet = new DatagramPacket(byt, byt.length);/ 接收socket.receive(packet);/ 获取发送方ipInetAddress address = packet.getAddress();String hostAddress = address.getHostAddress();/ 获取发送方端口号int port = packet.getPort();/ 获取数据byte data = packet.getData();/ 获取数据长度int dataLen = packet.getLength();System.out.println(IP: + hostAddress + 端口号: + port + 发送了: + new String(data, 0, dataLen); catch (IOException e) e.printStackTrace(); finally socket.close();System.out.println(接收端接受完毕.);2.2.5. 案例二:循环发送接收通过控制台录入用户信息,使用UDP 发送出去,另外一个UDP进行接收发送端可以持续发送信息,接收端可以持续接收信息.当发送端输入bye 结束.发送方public class TestUdpSend public static void main(String args) / 发送端System.out.println(这是UDP发送端,即将发送数据);DatagramSocket socket = null;/ 创建Sockettry socket = new DatagramSocket();BufferedReader br = new BufferedReader(new InputStreamReader(System.in);while (true) System.out.println(请输入发送信息:);String message = br.readLine();if (!bye.equals(message) break;/ 准备数据包,封装数据DatagramPacket packet = new DatagramPacket(message.getBytes(),message.getBytes().length,InetAddress.getByName(), 50000);/ 发送数据socket.send(packet); catch (IOException e) e.printStackTrace(); finally / 关闭关闭sockesocket.close();System.out.println(发送端数据数据发送完毕);接收方public class TestUdpReverse public static void main(String args) System.out.println(这是UDP接收端,准备接收数据);/ 创建Socket,指定端口DatagramSocket socket = null;try socket = new DatagramSocket(50000);/ 创建数组byte byt = new byte1024;/ 创建packetDatagramPacket packet = new DatagramPacket(byt, byt.length);while (true) / 接收数据socket.receive(packet);/ 获取发送发ipString ip = packet.getAddress().getHostAddress();/ 获取发送方端口int port = packet.getPort();/ 获取数据长度int dataLen = packet.getLength();/ 获取数据byte data = packet.getData();/ 转为字符串String mess = new String(data, 0, dataLen);System.out.println(发送方: + ip + 端口: + port + 发送了: + mess); if (bye.equals(mess) break; catch (IOException e) e.printStackTrace(); finally socket.close();2.3. Java的TCP面向连接, 数据安全, 区分服务器端和客户端.TCP分为Socket(客户端)和ServerSocket(服务端)需要分别建立客户端和服务器端客户端和服务端建立连接后,通过Socket中的IO流进行数据的传输需要关闭关闭socket同样,客户端与服务器端是两个独立的应用程序。2.3.1. TCP客户端第一步:创建客户端Socket需要指定连接到服务器的地址和端口号, 并尝试连接客户端需要明确服务器的ip地址以及端口,这样才可以去试着建立连接,如果连接失败,会出现异常。Socket socket = new Socket(20, 8888);第二步:连接成功获取输入输出流连接成功,说明客户端与服务端建立了通道,那么通过IO流就可以进行数据的传输,而Socket对象已经提供了输入流和输出流对象,通getInputStream(),getOutputStream()获取即可。socket.getInputStream();socket.getOuputStream();第三步: 将数据写出到服务端使用字节输出流的write() 方法第四步:关闭socket调用close方法连接成功之后获取输入输出流socket.getInputStream();socket.getOuputStream();获取流之后就可以通过输入输出流发送和读取数据了, 客户端的输入流连接服务端输出流, 客户端输出流连接服务端输入流客户端案例:public class TcpClient public static void main(String args) throws IOException, IOException System.out.println(客户端启动.);/ 创建客户端Socket socket = new Socket(, 50000);/ 与服务端建立连接,获取输入输出流InputStream in = socket.getInputStream();OutputStream out = socket.getOutputStream();/ 将数据写出到服务端System.out.println(客户端发送数据.);out.write(Tcp,你好我是客户端.getBytes();/ 关闭socketout.close();2.3.2. TCP服务端:第一步: 创建服务端ServerSocket, 需要指定端口号. 客户端连接的就是这个端口.java.lang.Object .ServerSocket创建ServerSocketServerSocket serverSocket = new ServierSocket(8888);第二步:和客户端建立连接通过accept方法Socket accept() 侦听并接受到此套接字的连接。该方法会侦听是否有客户端连接,如果有建立连接,并获取客户端的Socket也就是说服务端创建之后可以获取客户端连接, 返回一个Socket对象, 这个Socket就是和客户端连接的SocketSocket socket = serverSocket.accept();第三步: 接受客户端的数据,获取客户端的数据服务端获取这个socket的输入输出流, 就可以和客户端发送接收数据了socket.getInputStream();socket.getOutputStream();第五步:获取客户端的ip地址和端口号使用服务端获取的Socket 获取ip地址和端口.InetAddress getInetAddress() 返回套接字连接的地址。int getPort() 返回此套接字连接到的远程端口。第四步:关闭客户端和服务端在服务端中分别调用close方法.2.3.3. 案例一:客户端向服务端发送数据,服务端获取并进信息打印在控制台.public class TcpServer public static void main(String args) throws IOException System.out.println(服务端启动:);/ 服务端,监听端口ServerSocket server = new ServerSocket(50000);/ 使用acept进入侦听状态,获取客户端数据Socket socket = server.accept();/ 获取输入流输出流InputStream in = socket.getInputStream();OutputStream out = socket.getOutputStream();/ 获取客户端ip,端口InetAddress inetAddress = socket.getInetAddress();String ip = inetAddress.getHostAddress();int port = socket.getPort();/ 获取客户端数据byte byt = new byte1024;System.out.println(服务端接受数据:);int len = in.read(byt);String mess = new String(byt, 0, len);System.out.println(该客户端: + ip + : + port + 发送了: + mess);/ 关闭客户端socket.close();/ 关闭服务端server.close();2.3.4. 案例二客户端和服务端实现交互客户端给服务端发送信息,并接收服务端的回馈信息。例如:首先客户端向服务器通话客户端:你好吗?服务器服务器接到信息服务器:收到客户端消息客户端说:你好吗?服务器服务器回馈信息服务器:收到客户端消息客户端说:你好吗?服务器说:我很好客户端接到服务器的信息客户端:你好吗?服务器客户端: 收到服务器消息服务器说: 我很好客户端:public class TcpClient public static void main(String args) throws IOException, IOException System.out.println(客户端启动.);/ 创建客户端Socket socket = new Socket(, 50000);/ 与服务端建立连接,获取输入输出流InputStream in = socket.getInputStream();OutputStream out = socket.getOutputStream();BufferedReader br = new BufferedReader(new InputStreamReader(System.in);byte byt = new byte1024;while (true) / 将数据写出到服务端System.out.println(客户端发送数据.);System.out.println(你说:);String mess = br.readLine();System.out.println(你告诉了服务端:);out.write(mess.getBytes();/ 获取服务端的回话int len = in.read(byt);System.out.print(服务端告诉我了:);System.out.println(new String(byt, 0, len);if (bye.equals(mess) break;/ 关闭socketout.close();服务端:public class TcpServer public static void main(String args) throws IOException System.out.println(服务端启动:);/ 服务端,监听端口ServerSocket server = new ServerSocket(50000);/ 使用acept进入侦听状态,获取客户端数据Socket socket = server.accept();/ 获取输入流输出流InputStream in = socket.getInputStream();OutputStream out = socket.getOutputStream();/ 获取客户端ip,端口InetAddress inetAddress = socket.getInetAddress();String ip = inetAddress.getHostAddress();int port = socket.getPort(); byte byt = new byte1024; BufferedReader br = new BufferedReader(new InputStreamReader(System.in);while (true) / 获取客户端数据System.out.println(服务端接收数据:);int len = in.read(byt);String mess = new String(byt, 0, len);System.out.println(客户端: + ip + : + port + 告诉了服务端: + mess);/ 向客户端回话.System.out.println(你要告诉客户端:);String str = br.readLine();out.write(str.getBytes();if (bye.equals(mess) break;/ 关闭客户端socket.close();/ 关闭服务端server.close();2.3.5. 案例三:服务器可以客户端的连接.客户端通过键盘录入数据,发送到服务端,服务端接收到数据后,转换成大写在返回给客户端。需求:服务器可以客户端的连接.客户端通过键盘录入数据,发送到服务端,服务端接收到数据后,转换成大写在返回给客户端。客户端:public class Cilent public static void main(String args) throws UnknownHostException,IOException System.out.println(客户端启动.);Socket socket = new Socket(, 50000);InputStream in = socket.getInputStream();OutputStream out = socket.getOutputStream();BufferedReader br = new BufferedReader(new InputStreamReader(System.in);System.out.println(请录入:);String mess = br.readLine();out.write(mess.getBytes();System.out.println(-获取服务器的回馈-);byte byt = new byte1024;int len = in.read(byt);System.out.println(new String(byt, 0, len);socket.close();服务端:public class Cilent public static void main(String args) throws UnknownHostException,IOException System.out.println(客户端启动.);Socket socket = new Socket(, 50000);InputStream in = socket.getInputStream();OutputStream out = socket.getOutputStream();BufferedReader br = new BufferedReader(new InputStreamReader(System.in);System.out.println(请录入:);String mess = br.readLine();out.write(mess.getBytes();System.out.println(-获取服务器的回馈-);byte byt = new byte1024;int len = in.read(byt);System.out.println(new String(byt, 0, len);socket.close();2.3.6. 多线程服务器服务器一般是为多个客户端同时服务的, 当每个客户端连接到服务器时, 可以开一条单独的线程处理这个连接.服务器端:public class Server public static void main(String args) throws IOException System.out.println(服务器启动.);ServerSocket server = new ServerSocket(50000);while (true) Socket socket = server.accept();ServerRunnable serverRunnable = new ServerRunnable(socket);Thread t1 = new Thread(serverRunnable);t1.start();class ServerRunnable implements Runnable Socket socket;ServerRunnable(Socket socket) this.socket = socket;Overridepublic void run() try InputStream in = socket.getInputStream();OutputStream out = socket.getOutputStream();byte byt = new byte1024;int len = in.read(byt);String str = new String(byt, 0, len);System.out.println(str);System.out.println(-服务器转大写-);String upperCase = str.toUpperCase();System.out.println(upperCase);/ 转大写,写回给客户端out.write(upperCase.getBytes(); catch (IOException e) e.printStackTrace(); finally try socket.close(); catch (IOException e) e.printStackTrace();2.3.7. 上传文件分析:先启动服务器,再启动客户端.客户端和服务端需要建立连接,服务端向客户端反馈信息.告知客户端”连接成功,请上传文件路径:客户端:一: 客户端需要检测文件是否存在,是否是文件.二: 客户端将文件名,和文件的长度发给服务器,服务器以此判断文件是否存在,文件大小用以验证文件是否上传完毕.三: 客户端根据服务器端的反馈信息,如果服务器存在该文件,上传结束,不存在开始上传.四: 客户端开始上传, 使用字节输入流,将文件加载到输入流中,读取输入流,通过socket的输出流写到服务器.五: 服务器:根据客户传送的信息,判断文件是否存在如果存在不再上传,需
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 济南市2024-2025学年七年级上学期语文期末测试试卷
- 高铁安检课件
- 高配值班基本知识培训课件
- 电费业务知识培训课件
- 电脑课件无法使用浏览器问题解决
- 高血压脑出血的护理
- 高血压测量科普课件
- 电脑知识培训渭南课件
- 高考最后冲刺课件
- 电脑洗车水枪课件
- DB41T 1419-2017 振动拌和骨架密实水泥稳定碎石基层施工技术规范
- 2024-2025学年山东省淄博市桓台县四年级上学期数学期中考试试题
- 《公路建设项目文件管理规程》
- 《实践论》(原文)毛泽东
- 佳能-600EX-相机说明书
- ISO27001信息安全管理体系培训资料
- DB34T 3678-2020 内河航道疏浚工程施工技术规程
- 《绝对值》教学课件
- 《进一步规范管理燃煤自备电厂工作方案》发改体改〔2021〕1624号
- 制造业智能化生产线改造方案提升生产效率
- 重庆抗战历史文化概述
评论
0/150
提交评论