InetAddress ip = InetAddress.getByName(host);//host可以是计算机名字也可以是IP地址如127.0.0.1 复制代码
在程序中使用scoket进行通信,使用socket通信需要指定IP、端口、协议(UDP、TCP);数据发送分为两步:1、第一步是监听(等待数据发送过来),用来接收数据,需指定监听的端口;2、第二部是发送(需要指定发送到哪个计算机:IP地址,该计算机的哪个程序:Port号)。
socket中分为发送端和接收端:发送端一般为客户端,接收端一般为服务端。
一般有多个客户端,一个服务端。
UDP协议无需建立连接,直接向接收端发送数据报,不用考虑对方是否接收到数据报,只需要向接收方发送就行,至于接收方有没有接收到发送端不用管。所以使用UDP协议进行网络数据传输是不可靠的,但是速度快!
使用UDP协议开发发送端:用DatagramSocket发送数据:
DatagramSocket ds = new DatagramSocket();//socket套接字 复制代码
用DatagramPacket作为包裹(发送的数据内容):
byte[] buf = "你好,我想给你发送数据!".getBytes();//字节数组 int length = buf.length;//发送的长度 InetAddress address = InetAddress.getByName("127.0.0.1");//指定接收端的IP地址 int port = 7878;//指定接收端的监听端口号,与接收端对应 DatagramPacket dp = new DatagramPacket(buf, length, address, port);//待发送的包裹 复制代码
send()发送数据,close()释放资源。
ds.send(dp);//发送1次 //ds.send(dp);//发送2次 ... //ds.send(dp);//发送n次 ds.close();//发送完毕,释放资源 复制代码
举个栗子:chestnut::
//UDP发送端 public class Demo2_UDP_Send { public static void main(String[] args) throws Exception { DatagramSocket ds = new DatagramSocket();//socket套接字 byte[] buf = "你好,我想给你发送数据!".getBytes();//字节数组 int length = buf.length;//发送数据的长度 InetAddress address = InetAddress.getByName("127.0.0.1");//指定接收端的IP地址 int port = 7878;//指定接收端的端口号 DatagramPacket dp = new DatagramPacket(buf, length, address, port);//待发送的包裹 ds.send(dp);//发送 ds.close();//发送完毕,释放资源 } } 复制代码
使用UDP协议开发接收端: 用DatagramSocket来监听发送端发送过来的数据:
DatagramSocket ds = new DatagramSocket(7878);//接收端的监听端口 复制代码
用DatagramPacket作为接收数据的容器:
byte[] buf = new byte[1024]; int length = buf.length; DatagramPacket dp = new DatagramPacket(buf, length);//直接作为接收数据的容器 复制代码
receive()接收数据,程序会在这里等待数据的到来:
ds.receive(dp);//等待数据到来 复制代码
与发送端一样,接收到数据之后同样需要释放对象ds的资源:
ds.close();//接收到数据,释放资源 复制代码
举个栗子:chestnut::
//UDP接收端 public class Demo3_UDP_Receive { public static void main(String[] args) throws Exception { DatagramSocket ds = new DatagramSocket(7878);//接收端的监听端口 byte[] buf = new byte[1024]; int length = buf.length; DatagramPacket dp = new DatagramPacket(buf, length);//直接作为接收数据的容器 ds.receive(dp);//等待数据到来 String str = new String(dp.getData(), 0, dp.getLength()); System.out.println(str);//输出发送过来的数据 ds.close();//接收到数据,释放资源 } } 复制代码
程序运行结果:
接收端的其他信息获取:
dp.getAddress();//获取发送端的IP地址 dp.getPort();//获取发送端的端口号 复制代码
1、新建一个SendThread发送线程类:
public class SendThread extends Thread { private int port; public SendThread(int port) { this.port=port; } @Override public void run() { DatagramSocket ds=null; try { ds = new DatagramSocket(); Scanner inputstr = new Scanner(System.in);//输入数据 while (true) { String str = inputstr.nextLine(); if (str.equals("end")) break; byte[] buf = str.getBytes();//字节数组 int length = buf.length;//发送数据的长度 InetAddress address = InetAddress.getByName("127.0.0.1");//指定接收端的IP地址 //int port = 7878;//指定接收端的端口号 DatagramPacket dp = new DatagramPacket(buf, length, address, port);//发送包裹 ds.send(dp);//发送 } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (ds!=null) {//有数据传输,所以需要释放资源 ds.close(); } } } } 复制代码
2、再建一个ReceiveThread接收线程类:
public class ReceiveThread extends Thread { private int port; public ReceiveThread(int port) { this.port=port; } @Override public void run() { DatagramSocket ds=null; try { ds = new DatagramSocket(port);//指定端口号来监听数据,与发送端发送数据包指定的端口相对应 while (true) { byte[] buf = new byte[1024]; int length = buf.length; DatagramPacket dp = new DatagramPacket(buf, length);//作为接收数据的容器 ds.receive(dp);//等待数据到来 String str = new String(dp.getData(), 0, dp.getLength()); System.out.println("收到来自端口"+dp.getPort()+"的消息:"+str);//输出发送过来的数据 } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (ds!=null) {//有数据传输,所以需要释放资源 ds.close(); } } } } 复制代码
3、新建Chant_User01类(用户1):
public class Chant_User01 { public static void main(String[] args) { new SendThread(7878).start();//用户1的发送线程,7878端口为用户2的接收线程监听端口 new ReceiveThread(7879).start();//用户1的接收线程,7879监听来自用户2发送的数据 } } 复制代码
4、新建Chant_User02类(用户2):
public class Chant_User02 { public static void main(String[] args) { new ReceiveThread(7878).start();//用户2的接收线程,7878监听来自用户1发送的数据 new SendThread(7879).start();//用户2的发送线程,7879端口为用户1的接收线程监听端口 } } 复制代码
实现效果:
用户1:
用户2:
TCP协议需要通过三次握手建立连接,客户端与服务端之间是一个双向通道,既可以发送数据(使用输出流),也可以接收数据(使用输入流)。所以使用TCP协议进行网络数据传输是可靠的,但是速度较慢!
使用TCP协议开发客户端:客户端直接使用Socket,使用输出流OutputStream写入数据发送:
//TCP直接使用Socket Socket s = new Socket("127.0.0.1", 8888);//与TCP接收端建立连接 //使用输出流来传输数据 OutputStream output = s.getOutputStream(); output.write("ww.baidu.com".getBytes());//向服务端写入数据 s.close(); 复制代码
使用TCP协议开发服务端:服务端使用ServerSocket,accept()等待接收客户端发送的TCP连接请求,与客户端创建连接成功之后会返回一个socket对象,socket对象可以创建输入流InputStream接收客户端发送的数据,也可以创建输出流OutputStream发送数据。
ServerSocket ss = new ServerSocket(8888);//指定服务端监听端口 Socket client = ss.accept();//等待连接,建立与客户端的连接 InputStream input = client.getInputStream();//使用输入流来接收数据 byte[] buf = new byte[1024]; int length = input.read(buf);//等待客户端发送数据 client.close();//关闭连接 ss.close(); 复制代码
1、新建TCP_Client客户端类:
//TCP客户端 public class TCP_Client { public static void main(String[] args) throws Exception { Socket s = new Socket("127.0.0.1", 8888);//与Server端建立连接 OutputStream output = s.getOutputStream();//使用输出流来发送数据 InputStream input = s.getInputStream();//使用输入流接收来自Server的数据 /** * 匿名内部类创建一个线程来接收数据 * */ new Thread() { public void run() { byte[] buf = new byte[1024];//字节数组容器 int length = -1; try { while ((length = input.read(buf))!=-1) {//等待服务端发送数据 System.out.println(new String(buf, 0, length)); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }.start(); /** * 发送数据 * */ Scanner scanner = new Scanner(System.in); while (true) { String in_str = scanner.nextLine(); if (in_str.equals("end"))break; output.write(in_str.getBytes());//向Server端写入数据 } s.close();//关闭连接 } } 复制代码
1、新建TCP_Server服务端类:
//TCP连接的服务端 public class TCP_Server { public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(8888);//指定服务端监听端口 Socket client = ss.accept();//等待连接,建立与客户端的连接 System.out.println("客户端已连接进来!"); InputStream input = client.getInputStream();//使用输入流来接收数据 OutputStream output = client.getOutputStream();//使用输出流发送数据 /** * 匿名内部类创建一个线程来发送数据 * */ new Thread() { public void run() { Scanner scanner = new Scanner(System.in); while (true) { String str = scanner.nextLine(); if (str.equals("end"))break; try { output.write(str.getBytes());//向客户端写入数据 } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }.start(); /** * 接收数据 * */ byte[] buf = new byte[1024]; int length = -1; while ((length = input.read(buf))!=-1) {//等待客户端发送数据 System.out.println(new String(buf, 0, length)); } client.close();//关闭与客户端的连接 ss.close();//关闭监听 } } 复制代码
运行结果:
客户端:
服务端:
1、新建TCP_Server_Many类,可以接收多个客户端连接的TCP服务端和处理多个客户端的数据:
public class TCP_Server_Many { public static void main(String[] args) { new VerbClientConnect().start();//启动服务端监听线程监听多个客户端的连接 } } //监听多个客户端的连接 class VerbClientConnect extends Thread { @Override public void run() { try { ServerSocket serverSocket = new ServerSocket(8888); int i=0; while (true) { Socket socket = serverSocket.accept();//等待请求连接 i++; System.out.println("接收到一个客户端的连接:Client"+i+socket.getInetAddress()); new ClientMessage(socket,i).start(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } //处理客户端发送的消息 class ClientMessage extends Thread { private Socket socket; private int i; public ClientMessage(Socket socket, int i) { this.socket=socket; this.i=i; } @Override public void run() { try { InputStream input = socket.getInputStream();//使用输入流来接收数据 byte[] buf = new byte[1024]; int length = -1; while ((length = input.read(buf))!=-1) {//等待客户端发送数据 System.out.println("来自客户端Client"+i+"的消息:"+new String(buf, 0, length)); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (socket!=null) { try { socket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } 复制代码
2、新建TCP_Client_Many类,可以发送多条数据的TCP客户端:
public class TCP_Client_Many { public static void main(String[] args) throws Exception { Socket socket = new Socket("127.0.0.1", 8888);//请求连接 OutputStream output = socket.getOutputStream();//使用输出流来发送数据 Scanner scanner = new Scanner(System.in); while (true) { String str = scanner.nextLine(); if (str.equals("end"))break; output.write(str.getBytes());//向服务端发送数据 } socket.close(); } } 复制代码
运行效果:
Client1:
Client2:
Client3:
服务端:
今日寄语:
欢迎关注个人微信公众号: 桃李报春