java udp与tcp
一:基础 NET基本对象java.net.InetAddress类的使用
IP地址是IP使用的32位(IPv4)或者128位(IPv6)位无符号数字,它是传输层协议TCP,UDP的基础。InetAddress是Java 对IP地址的封装,在java.net中有许多类都使用到了InetAddress,包括 ServerSocket,Socket,DatagramSocket等等。
InetAddress的实例对象包含以数字形式保存的
IP地址,同时还可能包含主机名(如果使用主机名来获取InetAddress的实例,或者使用数字来构造,并且启用了反向主机名解析的功能)。
InetAddress类提供了将主机名解析为IP地址(或反之)的方法。
InetAddress的构造函数不是公开的(public),所以需要通过它提供的静态方法来获取,有以下的方法:
static InetAddress[] getAllByName(String host)
static InetAddress getByAddress(byte[] addr)
static InetAddress getByAddress(String host,byte[] addr)
static InetAddress getByName(String host)
static InetAddress getLocalHost()
实例代码:
import java.net.InetAddress; import java.net.UnknownHostException; public class Demo { /** * @param args * @throws UnknownHostException */ public static void main(String[] args) throws UnknownHostException { //获取本地主机的IP地址对象 //InetAddress inet = InetAddress.getLocalHost(); //获取任意一台主机的IP地址对象 InetAddress inet = InetAddress.getByName("10.2.156.26"); //获取本地主机的ip地址 String ip = inet.getHostAddress(); //获取本机主机的主机名 String name = inet.getHostName(); System.out.println(ip+":"+name); } }
二:udp相关代码
1:使用udp协议实现数据的发送
1:创建Socket发送端
2:明确要发送的数据
3:把要发送的数据封装成数据报包
4:使用Socket的发送功能发送数据
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; public class Send1 { /** * 使用udp协议实现数据的发送 * 1:创建Socket发送端 * 2:明确要发送的数据 * 3:把要发送的数据封装成数据报包 * 4:使用Socket的发送功能发送数据 * @throws IOException */ public static void main(String[] args) throws IOException { System.out.println("发送方启动......"); //1:创建Socket发送端---确定了使用的协议 DatagramSocket ds = new DatagramSocket(); //2:明确要发送的数据 String data = "明天放假"; byte[] b = data.getBytes(); //3:把要发送的数据封装成数据报包 //数据报包中包含了要发送的数据,接收数据的主机的IP地址对象,以及接收方使用哪个端口来接收 DatagramPacket dp = new DatagramPacket(b,b.length,InetAddress.getByName("10.2.156.15"),22222); //4:使用Socket的发送功能发送数据 //该方法内部使用的输出流,向网络上的另一台主机输出数据 ds.send(dp); ds.close(); } }
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class Receive1 { /** * 使用udp协议实现数据的接收 * 1:创建Socket端点,同时要监听一个端口 * 2:创建用来接收数据的数据报包 * 3:使用Socket的接收功能来接收数据 * @throws IOException */ public static void main(String[] args) throws IOException { System.out.println("接收方启动......"); //1:创建Socket端点 DatagramSocket ds = new DatagramSocket(22222); //2:创建一个空的数据报包来接收发送过来的数据报包 byte[] arr = new byte[1024]; DatagramPacket dp = new DatagramPacket(arr, arr.length); //使用Socket的接收功能来接收数据 ds.receive(dp); //解析数据 //获取发送过来的数据 byte[] data = dp.getData(); String shuju = new String(data,0,dp.getLength()); //获取发送方的ip地址 String ip = dp.getAddress().getHostAddress(); //获取发送方发送数据使用的端口 int port = dp.getPort(); System.out.println(ip+":"+port+":"+shuju); } }
2:使用udp实现可以一直接收数据
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class Send2 { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line = null; while ((line = br.readLine()) != null) { DatagramPacket dp = new DatagramPacket(line.getBytes(), line.length(), InetAddress.getByName("10.2.156.26"), 10001); ds.send(dp); if ("over".equals(line)) { System.out.println("程序结束!"); break; } } ds.close(); br.close(); } }
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class Receive2 { /** * 使用udp实现可以一直接收数据 * @throws IOException */ public static void main(String[] args) throws IOException { System.out.println("接收方启动....."); // 创建Socket端点,同时监听一个端口 DatagramSocket ds = new DatagramSocket(33333); while(true) { byte[] b = new byte[1024]; DatagramPacket dp = new DatagramPacket(b, b.length); ds.receive(dp); String data = new String(dp.getData(),0,dp.getLength()); String ip = dp.getAddress().getHostAddress(); System.out.println(ip+":"+data); } //ds.close(); } }
3:使用udp实现既能发送也能接收---聊天程序
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; public class UdpChat { /** * 使用udp实现既能发送也能接收---聊天程序 * 发送的同时还能接收,使用多线程 * 创建一个线程负责发送 * 创建一个线程负责接收 * @throws SocketException */ public static void main(String[] args) throws SocketException { DatagramSocket sendSocket = new DatagramSocket(); DatagramSocket receiveSocket = new DatagramSocket(44444); new Thread(new Send(sendSocket)).start(); new Thread(new Receive(receiveSocket)).start(); } } //描述接收任务 class Receive implements Runnable { private DatagramSocket socket; public Receive(DatagramSocket socket) { this.socket = socket; } @Override public void run() { while(true) { byte[] buf= new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); try { socket.receive(dp); String data = new String(dp.getData(),0,dp.getLength()); String ip = dp.getAddress().getHostAddress(); if("baibai".equals(data)) { System.out.println(ip+"离开了,不聊了"); } System.out.println(ip+":"+data); } catch (IOException e) { e.printStackTrace(); } } } } //描述发送任务 class Send implements Runnable { private DatagramSocket socket; public Send(DatagramSocket socket) { this.socket = socket; } @Override public void run() { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String line = null; try { while((line = br.readLine())!=null) { byte[] b = line.getBytes(); DatagramPacket dp = new DatagramPacket(b,b.length,InetAddress.getByName("10.2.156.255"),44444); socket.send(dp); if("baibai".equals(line)) { break; } } br.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
三:tcp相关代码
1:使用Tcp实现数据的发送(在服务器端把字符串变成大写返回到客户端)
代码:
package tcp; //172.17.9.1 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; /** * 使用Tcp实现数据的发送 * 1:创建Socket端点,同时指明连接的服务器的Ip地址和端口 * 2:从 Socket流中获取输出流 * 3:使用输出流向服务器端写入数据 * * @throws IOException * @throws UnknownHostException */ public class Client { public static void main(String[] args) throws IOException { // 创建Tcp协议的客户端,同时指明连接的服务器的Ip地址和端口 // 如果这条语句执行成功,不但创建了一个客户端对象,同时也和服务器端连接成功 // 如果连接成功,说明和服务器端建立了一条通道 // 这条通道就是Socket流(也就是客户端对象),Socket流中既有字节输入流,也有字节输出流 Socket s = new Socket(InetAddress.getByName("172.17.9.1"), 8888); //创建读取键盘输入的数据的字符读取流 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); //创建发送小写字符串到服务器端的字符输出流 OutputStream os = s.getOutputStream(); PrintStream ps = new PrintStream(os, true); //创建接收服务器返回的大写字符串的字符读取流 InputStream is = s.getInputStream(); BufferedReader brr = new BufferedReader(new InputStreamReader(is)); //读取键盘输入的字符串并发给服务器端,并接收大写字符串 while (true) { String line = null; if ((line = br.readLine()) != null) { if ("over".equals(line)) { System.out.println("程序结束!!"); break; } ps.println(line);//发送小写字符串到服务器端 String str = brr.readLine();//接收服务器返回的大写字符串 System.out.println(str); } } brr.close(); ps.close(); br.close(); s.close(); } }
package tcp; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** *使用Tcp实现数据的接收 *1:创建Socket端点,同时监听一个端口 *2:获取客户端对象,也就是获取Socket对象,也就是获取流对象,从而和客户端使用同一个流 *3:从Socket流中获取输入流 *4:使用输入流读取客户端发送的数据 * @throws IOException */ public class Server { public static void main(String[] args) throws IOException { //1:创建Socket端点,同时监听一个端口 ServerSocket ss = new ServerSocket(8888); //获取客户端对象 Socket s = ss.accept(); //创建接收小写字符串的字符读取流 InputStream is = s.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); //创建发送大写字符串的字符输出流 OutputStream os = s.getOutputStream(); PrintWriter pw = new PrintWriter(os, true); //循环读取客户端,再发送大写字符串到客户端 while (true) { String line = br.readLine(); if ("over".equals(line)) break; else pw.println(line.toUpperCase()); } pw.close(); br.close(); s.close(); ss.close(); } }
2:实现文本文件的上传:上传完成时,服务器端返回"上传成功"
package tcp; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; /** * 实现文本文件的上传:上传完成时,服务器端返回"上传成功" * 客户端: * 1:读取本地的一个文件 * 2:发送到服务器端 * 3:接收服务器端返回的"上传成功" * @throws IOException * @throws UnknownHostException */ public class Client2 { /** * @param args * @throws IOException * @throws UnknownHostException */ public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket(InetAddress.getByName("172.17.9.1"), 9999); //创建读取文本文件的字符读取流 BufferedReader br = new BufferedReader(new FileReader( "tempFile\\Demo.java")); //创建发送到服务器端的字符输出流 OutputStream os = s.getOutputStream(); PrintWriter pw = new PrintWriter(os, true); //创建接收服务器端返回的"上传成功"的字符读取流 InputStream is = s.getInputStream(); BufferedReader brr = new BufferedReader(new InputStreamReader(is)); String line = null; //循环读取文件并写入到服务器端 while ((line = br.readLine()) != null) { pw.println(line); } //向服务器端发送结束标记 s.shutdownOutput();//向服务器发送结束标记==》结束的是输出 //接收服务器端返回的"上传成功" String res = brr.readLine(); System.out.println(res); br.close(); s.close(); } }
package tcp; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * 实现文本文件的上传:上传完成时,服务器端返回"上传成功" * 服务器端: * 1:接收客户端发送的数据 * 2:写入到一个本地文件 * 3:发送“上传成功” * @throws IOException */ public class Server2 { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(9999); //获取客户端对象 Socket s = ss.accept(); //创建接收客户端发送的数据的字符读取流 InputStream is = s.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); //创建写入到一个本地文件的字符输出流 BufferedWriter bw = new BufferedWriter(new FileWriter("tempFile\\Demo_copy.java")); //创建发送“上传成功”的字符输出流 OutputStream os = s.getOutputStream(); PrintWriter pw = new PrintWriter(os,true); //循环读取客户端发送的数据,写入到本地文件 String line = null; //读取的是客户端,所以读不到 null while((line = br.readLine())!=null) { bw.write(line); bw.newLine(); bw.flush(); } bw.close(); //发送“上传成功” pw.println("上传成功!!");//这里如果用户println,它会自动刷新,如果是write 他不会自动刷新 s.close(); ss.close(); } }
3:实现图片的上传
package tcp; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; /** * 实现图片的上传 * @throws IOException * @throws UnknownHostException */ public class client3 { /** * @param args * @throws IOException * @throws UnknownHostException */ public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket(InetAddress.getByName("172.17.9.1"),6666); //读取图片的字节读取流 FileInputStream fis = new FileInputStream("img\\img.jpg"); //发送到服务器端的字节输出流 OutputStream os = s.getOutputStream(); //读取上传成功的字节读取流 InputStream is = s.getInputStream(); //循环读取文件,并发送到服务器端 byte[] b = new byte[1024]; int len = 0; while((len = fis.read(b))!=-1)//==》读取字节的时候,返回的是int即读到的个数,参数为字符数组的引用 { os.write(b,0,len); } //向服务器端写入结束标记 s.shutdownOutput(); //读取上传成功 byte[] arr = new byte[1024]; int num = is.read(arr); System.out.println(new String(arr,0,num)); s.close(); } }
package tcp; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class Server3 { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(6666); Socket s = ss.accept(); InputStream is = s.getInputStream(); OutputStream os = s.getOutputStream(); FileOutputStream fos = new FileOutputStream("img\\img_copy.jpg"); byte[] b = new byte[1024]; int num = 0; while((num = is.read(b))!=-1) { fos.write(b,0,num); } String str = "上传成功!"; os.write(str.getBytes()); os.flush(); s.close(); ss.close(); } }
4:实现图片的同步上传
package tcp; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class client4 { /** * @param args * @throws IOException * @throws UnknownHostException */ public static void main(String[] args) throws UnknownHostException, IOException { Socket s = new Socket(InetAddress.getByName("172.17.9.1"),6666); FileInputStream fis = new FileInputStream("img\\img.jpg"); OutputStream os = s.getOutputStream(); InputStream is = s.getInputStream(); byte[] b = new byte[1024]; int len = 0; while((len = fis.read(b))!=-1) { os.write(b,0,len); } byte[] arr = new byte[1024]; s.shutdownOutput(); int num = is.read(arr); System.out.println(new String(arr,0,num)); s.close(); } }
package PicUpload; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class PicUpload implements Runnable { Socket s; public PicUpload(Socket s) { this.s = s; } @Override public void run() { String ip = s.getInetAddress().getHostAddress(); System.out.println(ip + "连接到服务器.."); try { // 防止文件覆盖 int num = 0; File dir = new File("E:\\Image"); if (!dir.exists()) dir.mkdir(); File file = new File(dir, ip + "(" + (++num) + ")" + ".jpg"); while (file.exists()) file = new File(dir, ip + "(" + (++num) + ")" + ".jpg"); OutputStream os = s.getOutputStream(); InputStream is = s.getInputStream(); FileOutputStream fos = new FileOutputStream(file); byte[] b = new byte[1024]; int len = 0; while ((len = is.read(b)) != -1) { fos.write(b, 0, len); } String str = "上传成功!"; os.write(str.getBytes()); os.flush(); s.close(); } catch (IOException e) { e.printStackTrace(); } } }
package tcp; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import PicUpload.PicUpload; public class Server4 { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(6666); while(true) { Socket s = ss.accept(); new Thread(new PicUpload(s)).start(); } } }