Socket编程

网友投稿 725 2022-10-09

Socket编程

Socket编程

目录

​​概述​​

​​基于TCP的Socket通信​​

​​搭建工程​​

​​编码​​

​​SocketServerTCP类​​

​​SocketThreadTCP​​

​​SocketClientTCP​​

​​演示​​

​​基于UDP的Socket通信​​

​​编码​​

​​SocketServerUDP​​

​​SocketThreadUDP​​

​​SocketClientUDP​​

​​演示​​

​​代码​​

概述

Java开发的朋友们,对Socket都不会太陌生,在我们学习Java课程中,一般都会接触到。Socket是应用层与TCP/IP协议族通信的中间软件抽象层,特别是在Java开发中,JDK已经自带了Sokcet编码所需的接口,让我们更方便使用Socket来实现我们网络通讯功能。

由于最近有个项目刚好要用到Socket,在这里就重新复习一下。并分别实现基于TCP和UDP方式的Socket通信。

基于TCP的Socket通信

Socket通信是分别包含了服务端(Server)和客户端(Client)。

搭建工程

我们先建一个Java工程,方便后续扩展,我们还是采用了Maven方式。

给Project命个名和存放路径:

编码

弄个包(Package),方便区分:

SocketServerTCP类

Socket的服务端(Server),主要

因为我们采取多线程方式来处理客户端发送过来的数据,所以我们后面还需要加上一个多线程处理程序SocketThreadTCP。

package com.ispeasant.socket.tcp;import java.io.IOException;import java-.ServerSocket;import java-.Socket;public class SocketServerTCP { public static void main(String[] args) { try { // 通过ServerSocket类来创建服务端,端口为8888(TCP方式和UDP方式,使用的类是不一样) ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务端启动成功"); // 创建个Socket对象,可以理解为客户端 Socket socket = new Socket(); // 正常情况,我们都是先启动服务端(Server),然后再启动客户端(Client)来连接服务端(Server) // 因此,我们需要一直监听客户端(Client)的连接 while (true) { // 连接客户端(Client) socket = serverSocket.accept(); // 我们采用多线程方式,这样就可以同时连接多个客户端 SocketThreadTCP socketThreadTCP = new SocketThreadTCP(socket); socketThreadTCP.start(); } } catch (IOException e) { e.printStackTrace(); } }}

SocketThreadTCP

package com.ispeasant.socket.tcp;import java.io.*;import java-.Socket;import java.text.SimpleDateFormat;import java.util.Date;public class SocketThreadTCP extends Thread { // 创建一个Socket对象 private Socket socket = null; // 通过Socket对象与服务端作为入口,定义一个构建函数 public SocketThreadTCP(Socket socket) { this.socket = socket; } @Override public void run() { // 获取客户端传过来的数据 InputStream clientIS = null; InputStreamReader clientISR = null; BufferedReader clentBR = null; // 向客户端发送信息 OutputStream serverOS = null; PrintWriter serverPW = null; try { clientIS = socket.getInputStream(); clientISR = new InputStreamReader(clientIS); clentBR = new BufferedReader(clientISR); // 客户端发送过来的信息 String clientInfo = null; while ((clientInfo = clentBR.readLine()) != null) { System.out.println(clientInfo); } // 关掉socket的输入 socket.shutdownInput(); // 同时,我们也可以往客户端发送一些信息,以确认我们收到客户端的信息 serverOS = socket.getOutputStream(); serverPW = new PrintWriter(serverOS); // 加个时间戳,更好区分 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); Date date = new Date(System.currentTimeMillis()); serverPW.write(date + ":您好!我是服务端,已收到您的信息、"); serverPW.flush(); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭资源 if (serverPW != null) { serverPW.close(); } if (serverOS != null) { try { if (serverOS != null) { serverOS.close(); } if (clentBR != null) { clentBR.close(); } if (clientISR != null) { clientISR.close(); } if (socket != null) { socket.close(); } } catch (IOException e) { e.printStackTrace(); } } } }}

SocketClientTCP

Socket的客户端,可以用于与服务端(Server)通信。

package com.ispeasant.socket.tcp;import java.io.*;import java-.Socket;import java.text.SimpleDateFormat;import java.util.Date;public class SocketClientTCP { public static void main(String[] args) { try { // 创建socket对象,并指定服务端(Server的ip和端口) Socket socket = new Socket("localhost", 8888); // 向服务端(Server)发送信息 OutputStream clientOS = socket.getOutputStream(); PrintWriter clientPW = new PrintWriter(clientOS); // 加个时间戳 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); Date date = new Date(System.currentTimeMillis()); clientPW.write(date + ":您好,我是客户端。"); clientPW.flush(); // 关闭socket输出 socket.shutdownOutput(); // 接收服务端(Server)信息 InputStream serverIS = socket.getInputStream(); InputStreamReader serverISR = new InputStreamReader(serverIS); BufferedReader serverBR = new BufferedReader(serverISR); // 服务端(Server)信息 String serverInfo = null; while ((serverInfo = serverBR.readLine()) != null) { System.out.println(serverInfo); } // 关闭流 serverBR.close(); serverISR.close(); serverIS.close(); clientPW.close(); clientOS.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } }}

演示

先启动SocketServerTCP类:

由于我用的是IDEA开发工具,可以同时启动多个程序,接着我们就启动SocketClientTCP类。

这里可以看出,客户端已接收到服务端的信息,我们再看看服务端的情况。

因此,也可以看出服务端也是接收到了客户端发过来的信息。证明Socket的TCP通信,是已经成功了。

如果大家还想继续测试,就不要关停服务端的程序,再次启动客户端程序就可以了。

基于UDP的Socket通信

Socket除了支持TCP协议,也支持UDP协议。

编码

SocketServerUDP

package com.ispeasant.socket.udp;import java-.DatagramPacket;import java-.DatagramSocket;public class SocketServerUDP { public static void main(String[] args) { try { // UDP方式,采用的是DatagramSocket,与TCP是有点不一样 DatagramSocket udpSocket = new DatagramSocket(8888); System.out.println("----UDP服务端启动----"); // UDP方式,接收客户端发送过来的数据,也是有点不一样 DatagramPacket packetClient = null; byte[] dataClient = null; // 为了更方便测试,我们让服务端程序一直启动 while (true) { // 设定数据包的大小 dataClient = new byte[1024]; packetClient = new DatagramPacket(dataClient, dataClient.length); // 接收数据 udpSocket.receive(packetClient); // 采用多线程来处理数据 Thread thread = new Thread(new SocketThreadUDP(udpSocket, packetClient)); thread.start(); } } catch (Exception e) { e.printStackTrace(); } }}

SocketThreadUDP

package com.ispeasant.socket.udp;import java.io.IOException;import java-.DatagramPacket;import java-.DatagramSocket;import java.text.SimpleDateFormat;import java.util.Date;public class SocketThreadUDP implements Runnable { DatagramSocket socketUDP = null; DatagramPacket packetUDP = null; public SocketThreadUDP(DatagramSocket socketUDP, DatagramPacket packetUDP) { this.socketUDP = socketUDP; this.packetUDP = packetUDP; } @Override public void run() { // 客户端发过来的信息,是通过从packet里获取 String info = new String(packetUDP.getData(), 0, packetUDP.getLength()); // 加个时间戳,更好区分 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); Date date = new Date(System.currentTimeMillis()); System.out.println(date + "客户端:" + info); // 因为采用的是UDP方式,不像TCP那样有握手建立通信通道,所以我们向客户端返回信息时,是需要制定ip和端口 // 而这ip和端口信息,是可以通过packet来获取 // 向客户端发送信息 String server2Client = "我是服务端" + date; byte[] data = server2Client.getBytes(); try { socketUDP.send(new DatagramPacket(data, data.length, packetUDP.getAddress(), packetUDP.getPort())); } catch (IOException e) { e.printStackTrace(); } }}

SocketClientUDP

package com.ispeasant.socket.udp;import java-.DatagramPacket;import java-.DatagramSocket;import java-.InetAddress;import java.text.SimpleDateFormat;import java.util.Date;public class SocketClientUDP { public static void main(String[] args) { // 发送给服务端的信息 String info = "你好,我是客户端"; byte[] data = info.getBytes(); try { // 通过packet来打包数据发送给服务端 DatagramPacket clientPacket = new DatagramPacket(data, data.length, InetAddress.getByName("localhost"), 8888); // 通过DatagramSocket负责与服务端通信 DatagramSocket socket = new DatagramSocket(); socket.send(clientPacket); // 向服务端发送完数据后,我们可以看看服务端有没有信息返回给我们 byte[] serverData = new byte[1024]; DatagramPacket serverPacket = new DatagramPacket(serverData, serverData.length); socket.receive(serverPacket); // 接收到的服务端信息 String server2Client = new String(serverData,0,serverPacket.getLength()); // 加个时间戳,更好区分 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); Date date = new Date(System.currentTimeMillis()); System.out.println(date + ",服务端:" + server2Client); // 关闭sokcet socket.close(); } catch (Exception e) { e.printStackTrace(); } }}

演示

先启动SocketServerUDP程序:

接着启动SocketClientUDP程序:

我们再回到SocketServerUDP程序的控制台,看看有没有收到客户端的信息:

因此,Socket的UDP方式通信,也是成功的。

代码

我已经把代码上传到百度网盘,有需要的朋友可以-。

链接:https://pan.baidu.com/s/1PCUr7bGrFbOuei2DnogdkA

提取码:tdi4

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:微信小程序商城后台,微信小程序微店后台,接口基于FaShop(微信小程序商家入口)
下一篇:wxSortPickerView-微信小程序首字母排序选择表(微信列表字母排序)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~