900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 【小白学java】D33》》》网络编程 之 通信协议 分类 三要素 UDP网络通信(常

【小白学java】D33》》》网络编程 之 通信协议 分类 三要素 UDP网络通信(常

时间:2021-02-23 20:25:14

相关推荐

【小白学java】D33》》》网络编程 之 通信协议 分类  三要素  UDP网络通信(常

制作不易,各位友友们,大佬们给点鼓励!

点赞👍 👍 👍 收藏+关注 一键三连走起!

目录:

一、网络通信协议

(1) 网络通信协议

(2) TCP/IP协议

二、通信协议的分类

(1)UDP协议

(2)TCP协议

三、网络编程三要素

(1)网络通信协议

(2)IP地址

IP地址分类

(3)端口

四、InetAddress类

五、DatagramSocket类

六、DatagramPacket类

七、UDP网络通信

案例【一】:实现发送端和接收端聊天功能

案例【二】:实现各用户之间的通信

八、TCP网络通信

TCP通信的服务端

TCP通信的客户端

案例【一】:TCP通信实现文件上传

一、网络通信协议

(1) 网络通信协议

通过计算机网烙可以使多台计算机实现连接,位于同一个网络中的计算机在进行连接和通信时需要遵守一定的规则,在计算机网络中,这些连接和通信的规则被称为网络通信协议,它对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守才能完成数据交换,

(2) TCP/IP协议

TCP/IP协议叫做传输控制协议 或者 因特网互联协议( Transmission Control Prgtocol/Internet Protocol),它是Internet最基本、最广泛的协议。它定义了计算机如何连入因特网,以及数据如何在它们之间传输的标准,在它的内部包含一系列的用于处理数据通信的协议,并采用了4层的分层模型,每一层都呼叫它的下一层所提供的协议来完成自己的需求。

二、通信协议的分类

包中包含的类和接口,它们提供低层次的通信细节。我们可以直接使用这些类和接口,来专注于网络程序开发,而不用考虑通信的细节。

(1)UDP协议

UDP协议为用户数据报协议(User Datagram Protocol)。UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接。可以这样来理解,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样的接收端在收到数据时,也不会向发送端反馈是否收到数据。

因为使用UDP协议消耗资源小,通信效率高,所以通常都会用于音频、视频和普通数据的传输,例如视频会议都使用UDP协议,因为视频会议即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。但是在使用UDP协议传送数据时,由于UDP的面向无连接性,不能保证数据的完整性,所以在传输重要数据时不建议使用UDP协议。

注意;

UDP协议传输的数据大下限制在64KB以内,若超出这个范围就不能发送

网络传输的基本单位是数据报(Datagram)

(2)TCP协议

TCP协议为传输控制协议(Transmission Control Protocol)。它是*"面向连接** 的通信协议,即在传输数据之前,在发送端和接收端建立逻辑连接,然后再传输数据,它提供了两台计算机之间可靠无差错的数据传输。在TCP连接中必须要明确客户端与服务器端,由客户端向服务端发出连接请求,每次连接的创建都需要经过三次握手

完成了三次握手,连接建立之后,客户端和服务器就可以开始进行数据传输了。因为这种面向连接的特性,TCP协议可以保证传输数据的安全,所以应用十分广泛,例如下载文作、浏览网页等。

三、网络编程三要素

网络编程指的就是不同设备之间的数据传输

(1)网络通信协议

协议是指计算机网络通信必须遵守的规则。

(2)IP地址

(网络上设备的唯一标识)

IP地址是指互联网协议地址 ( Internet Protocol Address ),俗称IP。IP地址用来给一个网络中的计算机设备做唯一的编号。如果我们把"电脑"“比作"手机"的话,那么”“IP地址"就相当于是”“电话号码””。

IP地址分类:

IPv4是一个32位的二进制数,通常被分为4个字节,表示成a.b.c.d的形式,例如192.168.29.100。其中a、b、c、d都是0到255之间的十进制整数,所以最多可以表示42亿个IPv 4地址。

IPv6由于互联网的蓬勃发展,IP地址的需求量愈来愈大,但是网络地址资源有限,使得IP的分配越发紧张,所以,为了扩大IP地址空间,拟通过IPv6重新定义地址空间,采用128位地址长度,每16个字节一组,分成8组十六进制数,表示成 ABCD:EF01:2345:6789:ABCD:EF01:2345:6789,IPv6地址号称可以为全世界的每一粒沙子编上一个网址,这样就可以解决了网络地址资源数量不够的问题。

与IP有关的常用DOS命令:

1.查看本机IP地址:ipconfig2.检查网络是否联通:ping 空格 IP地址例如: ping 192.168.29.7 3.特殊的IP;本机IP地址:127.0.0.1 -localhost

(3)端口

端口是指设备上应用的唯一标识

端口号

端口号是用两个字节表示,取值范围0~65536,其中0-1023之间的端口号用于一些知名的网络服务和应用,普通应用程序需要使用1024及以上的端口号,如果端口号被另外一个应用程序占用,那么会导致启动失败,

常见到的端口号1.80端口 :网络端口2.数据库: mysql :3306 oracle:15213.tomcat服务器: 8080

四、InetAddress类

Java提供了一个类InetAddress,我们可以通过使用这个类来操作IP地址

InetAddress类表示Internet协议(IP)地址

该类的常用成员方法有:

1. static InetAddress getByName(String host)确定主机名称的IP地址,主机名称可以是机器名称,也可以是Ip地址2. String getHostName()获取此IP地址的主机名3. String getHostAddress()返回IP地址的字符串

五、DatagramSocket类

public class DatagramSocket extends Object implements Closeable,此类表示用于发送和接收数据报数据包的套接字。 数据报套接字是分组传送服务的发送或接收点。 在数据报套接字上发送或接收的每个数据包都被单独寻址和路由。 从一个机器发送到另一个机器的多个分组可以不同地路由,并且可以以任何顺序到达。在可能的情况下,新构建的DatagramSocket启用了SO_BROADCAST套接字选项,以允许广播数据报的传输。 为了接收广播数据包,DatagramSocket应该绑定到通配符地址。 在一些实现中,当DatagramSocket绑定到更具体的地址时,也可以接收广播分组。

该类的常用构造方法:

DatagramSocket() 构造数据报套接字并将其绑定到本地主机上的任何可用端口。 DatagramSocket(int port) 构造数据报套接字并将其绑定到本地主机上的指定端口。 DatagramSocket(int port, InetAddress laddr) 创建一个数据报套接字,绑定到指定的本地地址。

常用的成员方法:

void bind(SocketAddress addr) 将此DatagramSocket绑定到特定的地址和端口。void connect(InetAddress address, int port) 将套接字连接到此套接字的远程地址。 void connect(SocketAddress addr) 将此套接字连接到远程套接字地址(IP地址+端口号)。 InetAddress getInetAddress() 返回此套接字连接到的地址。 InetAddress getLocalAddress() 获取套接字所绑定的本地地址。 int getLocalPort() 返回此套接字绑定到的本地主机上的端口号。 SocketAddress getLocalSocketAddress() 返回此套接字绑定到的端点的地址。 int getPort() 返回此套接字连接到的端口号。 boolean isClosed() 返回套接字是否关闭。 boolean isConnected() 返回套接字的连接状态。 void receive(DatagramPacket p) 从此套接字接收数据报包。 void send(DatagramPacket p) 从此套接字发送数据报包。 void close() 关闭此数据报套接字。

六、DatagramPacket类

public final class DatagramPacket extends Object,该类表示数据报包。 数据报包用于实现无连接分组传送服务。 仅基于该数据包中包含的信息,每个消息从一台机器路由到另一台机器。 从一台机器发送到另一台机器的多个分组可能会有不同的路由,并且可能以任何顺序到达。 包传送不能保证。

该类常用的构造方法:

DatagramPacket(byte[] buf, int length) 构造一个 DatagramPacket用于接收长度的数据包 length DatagramPacket(byte[] buf, int length, InetAddress address, int port) 构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。 DatagramPacket(byte[] buf, int offset, int length) 构造一个 DatagramPacket用于接收长度的分组 length,指定偏移到缓冲器中。 DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 构造用于发送长度的分组数据报包 length具有偏移 ioffset指定主机上到指定的端口号。 DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) 构造用于发送长度的分组数据报包 length具有偏移 ioffset指定主机上到指定的端口号。 DatagramPacket(byte[] buf, int length, SocketAddress address) 构造用于发送长度的分组的数据报包 length指定主机上到指定的端口号。

常用的成员方法;

InetAddress getAddress() 返回该数据报发送或接收数据报的计算机的IP地址。 byte[] getData() 返回数据缓冲区。 int getLength() 返回要发送的数据的长度或接收到的数据的长度。 int getOffset() 返回要发送的数据的偏移量或接收到的数据的偏移量。 int getPort() 返回发送数据报的远程主机上的端口号,或从中接收数据报的端口号。 SocketAddress getSocketAddress() 获取该数据包发送到或正在从其发送的远程主机的SocketAddress(通常为IP地址+端口号)。 void setAddress(InetAddress iaddr) 设置该数据报发送到的机器的IP地址。 void setData(byte[] buf) 设置此数据包的数据缓冲区。 void setData(byte[] buf, int offset, int length) 设置此数据包的数据缓冲区。 void setLength(int length) 设置此数据包的长度。 void setPort(int iport) 设置发送此数据报的远程主机上的端口号。 void setSocketAddress(SocketAddress address) 设置该数据报发送到的远程主机的SocketAddress(通常是IP地址+端口号)。

七、UDP网络通信

UDP是不可靠的网络通信协议,在通信两端各建立一个Socket对象,这两个Socket只是发送数据、接收数据的对象

在Java中提供了DatagramSocket类作为Socket基类来进行UDP通信UDP发送数据:1.创建发送端的Socket对象(DatagramSocket)2.创建数据,指定ip地址和端口号和数据,3.调用DatagramPacket类的对象中的构造方法把数据打包,4.调用DatagramPacket方法send(DatagramPacket p)发送数据5.关闭发送端close()UDP接收数据:1.创建接收端的Socket对象(DatagramSocket)指定(绑定)端口号,运行所使用的的端口号2.创建数据包,用于接收数据3.调用Socket对象(DatagramSocket)的receive()方法接收数据4.解析数据包,在控制台显示 getData()5.关闭接收端close()

示例代码:

public class demo_serverUDP {public static void main(String[] args) throws IOException {//1.创建发送端的Socket对象(DatagramSocket)DatagramSocket socket = new DatagramSocket();// 2.创建数据,指定ip地址和端口号、数据//创建数据byte[] bytes="Hello, UDP !".getBytes();//指定ipInetAddress ip=InetAddress.getByName("10.7.156.103");//指定端口号int port=8888;//3.调用DatagramPacket类的对象中的构造方法打包数据DatagramPacket dp = new DatagramPacket(bytes, bytes.length, ip, port);// 4.调用DatagramPacket方法send()发送数据socket.send(dp);// 5.关闭发送端close()socket.close();}}

public class demo_clientUDP {public static void main(String[] args) throws IOException {//1.创建接收端的Socket对象(DatagramSocket),指定(绑定)端口号,运行所使用的的端口号DatagramSocket socket = new DatagramSocket(8888);// 2.创建数据包,用于接收数据byte[] bytes=new byte[1024];DatagramPacket dp = new DatagramPacket(bytes, 0, bytes.length);// 3.调用Socket对象(DatagramSocket) receive()方法接收数据socket.receive(dp);// 4.解析数据包,在控制台显示 getData()System.out.println("address/ip;\t"+dp.getAddress());System.out.println("data :\t"+dp.getData());System.out.println("length:\t"+dp.getLength());System.out.println("offset:\t"+dp.getOffset());System.out.println("port:\t"+dp.getPort());System.out.println("socketAddress/ip+端口号:\t"+dp.getSocketAddress());System.out.println("dataPacket:\t"+new String(dp.getData(),0,dp.getLength()));// 5.关闭接收端socket.close();}}

测试结果:

案例【一】:实现发送端和接收端聊天功能

示例代码+详细步骤:

发送端代码:

import .DatagramPacket;import .DatagramSocket;import .InetAddress;import java.util.Scanner;//案例【一】:实现发送端和接收端聊天功能public class demo01_SendUDP {public static void main(String[] args) throws Exception {//1.创建发送端的socket对象,指定发送端的端口号6666DatagramSocket datagramSocket = new DatagramSocket(6666);//2.创建数据(控制台输入数据),Scanner scanner = new Scanner(System.in);//3.while死循环实现多次发送while (true){//4.发送数据到接收端,//接收控制台输入的要发送的数据,并转换为byte数组String str =scanner.next();byte[] bytes = str.getBytes();//指定接收端的 ip 、portInetAddress receiveIP = InetAddress.getByName("10.7.156.103");int receivePort= 8888;//打包要发送的数据DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length, receiveIP, receivePort);//发送数据datagramSocket.send(datagramPacket);//发送端,判断什么时候退出聊天,键入“byebye”或者“拜拜”退出循环if(str.equals("byebye")|| str.equals("拜拜") )break;//5.发送端接收接收端返回的数据,解析打印byte[] bytes1 = new byte[1024];//发送端,创建接收包DatagramPacket datagramPacket1 = new DatagramPacket(bytes1, 0, bytes1.length);//发送端,解析数据datagramSocket.receive(datagramPacket1);//打印数据到控制台//将bytes1转换为String对象String str1 = new String(datagramPacket1.getData(), datagramPacket1.getOffset(), datagramPacket1.getLength());System.out.println("接收端返回的数据:\t"+str1);//判断接收端是否还要继续聊天if(str1.equals("byebye")|| str1.equals("拜拜") )break;}//6.调用close()方法,关闭聊天datagramSocket.close();}}

接收端代码:

import .DatagramPacket;import .DatagramSocket;import .InetAddress;import java.util.Scanner;public class demo02_RecieveUDP {public static void main(String[] args)throws Exception {//1.创建接收端socket对象,指定接收端的端口DatagramSocket datagramSocket = new DatagramSocket(8888);///2.创建数据(控制台输入数据),Scanner scanner = new Scanner(System.in);//3.while死循环实现多次发送while (true){//4.接收发送端发送的数据,解析打印byte[] bytes1 = new byte[1024];//创建接收包DatagramPacket datagramPacket1 = new DatagramPacket(bytes1, 0, bytes1.length);//解析数据datagramSocket.receive(datagramPacket1);//打印数据到控制台//将bytes1转换为String对象String str1 = new String(datagramPacket1.getData(), datagramPacket1.getOffset(), datagramPacket1.getLength());System.out.println("发送端返回的数据:\t"+str1);//判断发送端是否还要继续聊天if(str1.equals("byebye")|| str1.equals("拜拜") )break;//5.接收端发送数据到发送端,//接收控制台输入的要发送的数据,并转换为byte数组String str =scanner.next();byte[] bytes = str.getBytes();//指定发送端的 ip 、portInetAddress sendIP = InetAddress.getByName("10.7.156.103");int sendPort= 6666;//打包要发送的数据DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length, sendIP, sendPort);//发送数据到发送端datagramSocket.send(datagramPacket);//接收端,判断什么时候退出聊天,键入“byebye”或者“拜拜”退出循环if(str.equals("byebye")|| str.equals("拜拜") )break;}//6.调用close()方法,关闭聊天datagramSocket.close();}}

测试结果:

案例【二】:实现各用户之间的通信

分析:采用一个控制端负责打印各个客户端发送来的信息

示例代码

控制端Controller:

public class demo01_Controller {public static void main(String[] args) throws Exception{//1.创建控制台的socket对象,指定控制台的端口号7777DatagramSocket datagramSocket = new DatagramSocket(7777);//2.接收各个客户端client01/client02发送来的信息并打印Scanner scanner = new Scanner(System.in);while (true){byte[] bytes = new byte[1024];DatagramPacket datagramPacket = new DatagramPacket(bytes, 0,bytes.length);datagramSocket.receive(datagramPacket);String string = new String(datagramPacket.getData(),datagramPacket.getOffset(),datagramPacket.getLength());System.out.println(datagramPacket.getSocketAddress()+":\t"+string);}}}

客户端一:

public class demo02_client01 {public static void main(String[] args) throws Exception{//1.创建client01的socket对象,指定port=8888DatagramSocket datagramSocket = new DatagramSocket(8888);//2.发送数据到控制台 port=7777Scanner scanner = new Scanner(System.in);while (true){//获取键盘键入信息,打包指定控制台ip、portString string =scanner.next();byte[] bytes = string.getBytes();DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("10.7.156.103"), 7777);//发送数据datagramSocket.send(datagramPacket);}}}

客户端二;

public class demo03_client02 {public static void main(String[] args) throws Exception {//1.创建client02的socket对象,指定port=9999DatagramSocket datagramSocket = new DatagramSocket(9999);//2.发送数据到控制台 port=7777Scanner scanner = new Scanner(System.in);while (true){//获取键盘键入信息,打包指定控制台ip、portString string =scanner.next();byte[] bytes = string.getBytes();DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("10.7.156.103"), 7777);//发送数据datagramSocket.send(datagramPacket);}}}

客户端三:

public class demo03_client03 {public static void main(String[] args) throws IOException {//1.创建client03的socket对象,指定port=6666DatagramSocket datagramSocket = new DatagramSocket(6666);//2.发送数据到控制台 port=7777Scanner scanner = new Scanner(System.in);while (true) {//获取键盘键入信息,打包指定控制台ip、portString string = scanner.next();byte[] bytes = string.getBytes();DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("10.7.156.103"), 7777);//发送数据datagramSocket.send(datagramPacket);}}}

测试结果:

八、TCP网络通信

TCP通信能实现两台计算机之间的数据交互,通信的两端,要严格区分为客户端(Client )与服务端(Server )。

两端通信时的步骤:

1.服务端程序,需要事先启动,等待客户端的连接。2客户端主动连接服务器端,连接成功才能通信。服务端不可以主动连接客户端。

在Java中,提供了两个类用于实现TCP通信程序:

1.客户端: .socket 类,表示创建socket对象,向服务端发出连接请求,服务端响应请求,两者建立连接开始通信。2.服务端∶ .ServerSocket 类,表示创建ServerSocket对象,相当于开启一个服务,并等待客户端的连接,

TCP通信的服务端

TCP通信的服务器端用于接牧客户端的请求,读取客户端发送的数据,给客户端回写数据

Java中表示服务器的类:

在下的ServerSocket类,该类用于实现服务器套接字。

构造方法:ServerSocket (int port)创建绑定到特定端口的服务器的套挨字。注意;服务器端必须要知道是哪个客户端靖求的服务器,所以可以使用accept方法获取到请求的客户端的对象socket成员方法;Socket accept() 侦听并接受到此套接字的连接。

服务器端的实现步骤:

1,创建服务器ServerSocket类的对象和系统要指定的端口号2.使用ServerSocket类的对象中的accept()方法,获取到请求的客户端的对象Socket3.使用Socket对象中的getInputStream()方法,获叹网络字节输入流InputStream类的对象4,使用网络字书输入流InputStream对象中的read()方法,读取客户端发送来的数据5.使用Socket对象中的getOutputStream()方法,获取网络字节输出流OutputStream类的对象6.使用网络字节输出流OutputStream对象中的write()方法 ,给客户端回写数据7.调用close()方法,释放资源(Socket,ServerSocket)

示例代码;

public class demo01_serverTCP {public static void main(String[] args) throws IOException {//1,创建服务器ServerSocket类的对象和系统要指定的端口号ServerSocket serverSocket = new ServerSocket(8888);//2.使用ServerSocket类的对象中的accept()方法,获取到请求的客户端的对象SocketSocket socket = serverSocket.accept();//3.使用Socket对象中的getInputStream()方法,获叹网络字节输入流InputStream类的对象InputStream is = socket.getInputStream();//4,使用网络字书输入流InputStream对象中的read()方法,读取客户端发送来的数据byte[] bytes = new byte[1024];int read = is.read(bytes);System.out.println(new String(bytes,0,read));//5.使用Socket对象中的getOutputStream()方法,获取网络字节输出流OutputStream类的对象OutputStream os = socket.getOutputStream();//6.使用网络字节输出流OutputStream对象中的write()方法 ,给客户端回写数据String string ="你好,TCP客户端,我收到了你的请求!";byte[] bytes1 = string.getBytes();os.write(bytes1);//7.调用close()方法,释放资源(Socket,ServerSocket)socket.close();serverSocket.close();}}

TCP通信的客户端:

客户端会向服务器端发送连接请求,给服务器端发送数据,读取服务器端回写的数据

Java中表示客户端的类;

包下的Sochet类,该类实现客户端套接字。套接字是指两台机器间通信的端点,在套接字中包合了IP她址和编口号的网络单位

该类的构造方法有:

Socket(string host, int port)创建一个流套接字并将其连接到指定主机上的指定端口号。构造方法中的参数:String host:表示服务器主机的名称/服务器的IP地址int port:服务器的编口号

类成员方法有:

OutputStream getOutputStreom()返回此套接字的蜂出流。InputStream getInputStream()返回此套接字的输入流。void close()关团此套接字。

TCP客户端的实现步骤:

1.创建一个客户端对象.Socket并在构造方法绑定服务器的ip她址和端口号2.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream类的对象.3.使用网络字书输出流OutputStream类的对象中的write()方法,给服务器端发送数据4.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream类的对象5.使用网络字节输入流InputStream对象中的read()方法,读取服务器端回写的数据6.调用close()方法,释放资源( Socket)

注意;

1.客户端和服务器挑进行交互,必须使用socket中提供的网络流;不能使用自己创建的流对象2.在创建客户端的对象Socket时候会去请求服务器,并和服务器经过3次握手建立连接通路,那么这时候,如果服务器没有启动就会抛出异常;如果服务器已经启动了,那么就可以进行交互。

示例代码;

public class demo02_clientTCP {public static void main(String[] args) throws IOException {//1.创建一个客户端对象.Socket并在构造方法绑定服务器的ip她址和端口号Socket socket = new Socket("10.7.156.103", 8888);//2.使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream类的对象.OutputStream os = socket.getOutputStream();//3.使用网络字书输出流OutputStream类的对象中的write()方法,给服务器端发送数据String str ="你好,TCP服务器!";byte[] bytes = str.getBytes();os.write(bytes);//4.使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream类的对象InputStream is = socket.getInputStream();//5.使用网络字节输入流InputStream对象中的read()方法,读取服务器端回写的数据byte[] bytes1 = new byte[1024];int read = is.read(bytes1);System.out.println(new String(bytes1,0,read));//6.调用close()方法,释放资源( Socket)socket.close();}}

测试结果;

案例【一】:TCP通信实现文件上传

示例代码+详细分析步骤:

服务端:

/*服务器端:接收客户端上传的文件,并保存到到硬盘中,返回给客户端上传成功的信息实现步理:1.创建一个服务器serverSocket对象,和系统要指定的端口号2.使用ServerSocket对象中的accept方法,获取到请求的客户端socket对象3.使用Socket对象中的getInputStream()方法,获取到网络字节输入流InputStream类的对象4,判断上传的文件的目录是否存在,不存在则创建5.创建一个本地字节输出流FiLeOutputStream类的对象在杓造方法中绑定要输出的目的地6.使用网络字节输入流InputStream类的对象中的read()方法来读取客户端上传的文件7.使用本地字节输出流FiLeOutputStream类的对象中的write()方法将读取到的文件保存到服务器的硬盘上8.使用Socket对象中的getOutputStream()方法 , 获取网络字节输出流OutputStream类的对象9.使用网络字节输出流OutputStream对象中的write()方法,回发客户说"上传成功”的信息10.调用close()方法,释旋资源(FileOutputStream, Socket , serverSocket)*/public class demo_serverTCP {public static void main(String[] args) throws IOException {//1.创建一个服务器serverSocket对象,和系统要指定的端口号ServerSocket serverSocket = new ServerSocket(8888);//程序优化:使用while死循环,让服务器一直处于监听状态,提高程序的效率while (true){/*来一个客户端上传文件,就保存一个文件;可以使用多线程来优化,提高效率,来一个就开一个线程*/new Thread(new Runnable() {@Overridepublic void run() {//重写run方法,完成文件的上传//由于Runnable类public abstract void run()方法没有声明抛出异常,//子类重写方法时也不能声明抛出异常,只能使用try-catch来处理异常try{//2.使用ServerSocket对象中的accept方法,获取到请求的客户端socket对象Socket socket = serverSocket.accept();//3.使用Socket对象中的getInputStream()方法,获取到网络字节输入流InputStream类的对象InputStream is = socket.getInputStream();//4,判断上传的文件的目录是否存在,不存在则创建File file = new File("D:\\BigData\\java\\javalearn\\src\\com\\data\\upload");if (!file.exists()){file.mkdirs();}//5.创建一个本地字节输出流FiLeOutputStream类的对象在杓造方法中绑定要输出的目的地//优化:使用自定义的名称,可以防止同命的文件被覆盖,一般规则:域名+毫秒值+随机数String fileName="beiMuChen"+System.currentTimeMillis()+new Random().nextInt(99999)+".txt";FileOutputStream fos = new FileOutputStream("D:\\BigData\\java\\javalearn\\src\\com\\data\\upload\\"+fileName);//6.使用网络字节输入流InputStream类的对象中的read()方法来读取客户端上传的文件byte[] bytes = new byte[1024];int sum;while ((sum =is.read(bytes))!=-1){//7.使用本地字节输出流FiLeOutputStream类的对象中的write()方法将读取到的文件保存到服务器的硬盘上fos.write(bytes);}//8.使用Socket对象中的getOutputStream()方法 , 获取网络字节输出流OutputStream类的对象OutputStream os = socket.getOutputStream();//9.使用网络字节输出流OutputStream对象中的write()方法,回发客户说"上传成功”的信息os.write("上传成功".getBytes());//10.调用close()方法,释旋资源(FileOutputStream, Socket , serverSocket)fos.close();socket.close();}catch(Exception e){System.out.println(e);}}}).start();}//因为死循环,让服务器一直启动监听,所以就不用关闭serverSocket//serverSocket.close();}}

客户端:

/*客户端:读取本地要上传的文件、上传到服务器、接收服务器回发的数据实现步骤;1.创建一个本地字节输入流FiLeInputStream的对象,在构造方法中绑定要读取的数据源2.创建一个客户端socket对象,在构造方法中绑定服务器的IP地址和端口号3.调用Socket中的getOutputStream()方法,获取网络字节输出流OutputStream对象4.使用本地字节输入流FiLeInputStream的对象中的read()方法读取本地的文件5.使用网络字节输出流OutputStream对象中的write()方法将诱取到的文件上传到服务器6.使用Socket中的getInputStream()方法,获取网字节输入流InputStream的对象7.使用网络字节输入流InputStream的对象中的read()方法,读取服务回发的数据8.调用close()方法,释放资源(FileInputStream, Socket)*/public class demo_clientTCP {public static void main(String[] args) throws Exception {//1.创建一个本地字节输入流FiLeInputStream的对象,在构造方法中绑定要读取的数据源FileInputStream fis = new FileInputStream("D:\\BigData\\java\\javalearn\\src\\com\\data\\data1.txt");//2.创建一个客户端socket对象,在构造方法中绑定服务器的IP地址和端口号Socket socket = new Socket("10.7.156.103", 8888);//3.调用Socket中的getOutputStream()方法,获取网络字节输出流OutputStream对象OutputStream os = socket.getOutputStream();//4.使用本地字节输入流FiLeInputStream的对象中的read()方法读取本地的文件byte[] bytes = new byte[1024];int sum;while ((sum=fis.read(bytes))!=-1){//5.使用网络字节输出流OutputStream对象中的write()方法将诱取到的文件上传到服务器os.write(bytes);}/*解决阻塞问题: 上传完文件,给服务器发送一个结束的标记方法: void shutdownOutput( )禁用此套接字的输出流。对于TCP套接字,任何以前写入的激数据都将祧发送,并且后跟TCP的正常连接终止序列。*/socket.shutdownOutput();//6.使用Socket中的getInputStream()方法,获取网字节输入流InputStream的对象InputStream is = socket.getInputStream();while ((sum=is.read(bytes))!=-1){//7.使用网络字节输入流InputStream的对象中的read()方法,读取服务回发的数据System.out.println(new String(bytes,0,sum));}//8.调用close()方法,释放资源(FileInputStream, Socket)fis.close();socket.close();}}

测试结果:

【小白学java】D33》》》网络编程 之 通信协议 分类 三要素 UDP网络通信(常用类 案例) TCP网络通信

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。