最近在项目中可能要用到socket相关的东西来发送消息,所以初步研究了下socket的TCP和UDP实现方式,并且结合java1.5的concurrent.ExecutorService类来实现多线程。
具体实现方式见代码:
一、TCP方式:
1、服务端实现方式:
TCP的服务端实现方式主要用到ServerSocket类,接收等待客户端连接的方法是accept();
代码如下:类SocketServerTCP
1 private int port = 8823;
2 private ServerSocket serverSocket;
3 private ExecutorService executorService;// 线程池
4 private final int POOL_SIZE = 100;// 单个CPU线程池大小
5
6 public SocketServerTCP() {
7 try {
8 serverSocket = new ServerSocket(port);
9 executorService = Executors.newFixedThreadPool(Runtime.getRuntime()
10 .availableProcessors() * POOL_SIZE);
11 logger.info("端口号为" + port + "的服务器启动");
12 } catch (IOException e) {
13 e.printStackTrace();
14 }
15 }
16
17 public void service() {
18 System.out.println("socket初始化成功!");
19 logger.info("socket服务端初始化成功!");
20 while (true) {
21 Socket socket = null;
22 try {
23 // 接收客户连接,只要客户进行了连接,就会触发accept();从而建立连接
24 socket = serverSocket.accept();
25 executorService.execute(new CallService(socket));
26 } catch (Exception e) {
27 e.printStackTrace();
28 }
29 }
30 }
CallService类主要作用是接收到消息后,来实现具体业务。
代码如下:
1 /**
2 * 功能说明:执行具体业务的线程
3 */
4 class CallService implements Runnable {
5 Logger logger = Logger.getLogger(CallService.class);
6 private Socket socket;
7
8 private BufferedReader is;
9 private PrintWriter os;
10
11 public CallService(Socket socket) {
12 this.socket = socket;
13 }
14
15 public void run() {
16 try {
17 is = new BufferedReader(new InputStreamReader(socket.getInputStream()));
18 os = new PrintWriter(socket.getOutputStream());
19
20 String msg = is.readLine();
21
22 System.out.println("接到客户端消息" + msg);
23
24 //返回消息给客户端
25 String responseMsg="服务端返回消息:" + msg;
26 os.println(responseMsg);
27 os.flush();
28 } catch (IOException e) {
29 e.printStackTrace();
30 } finally {
31 try {
32 if (os != null) {
33 os.close();
34 }
35 if (is != null) {
36 is.close();
37 }
38 if (socket != null) {
39 socket.close();
40 }
41 } catch (IOException e) {
42 e.printStackTrace();
43 }
44 }
45 }
服务器启动方式:
1 public static void main(String[] args) {
2 new SocketServerTCP().service();
3 }
2、TCP客户端实现代码
客户通过new Socket(ip, port)创建一个socket,并通过PrintWriter来向服务器发送消息
1 public class SocketClientTCP {
2 public String sendMsg(String ip, int port, String msg) {
3 Socket client = null;
4 try {
5 // 创建Socket
6 client = new Socket(ip, port);
7
8 // 向服务器发送消息
9 PrintWriter out = new PrintWriter(new BufferedWriter(
10 new OutputStreamWriter(client.getOutputStream())), true);
11 out.println(msg);
12 out.flush();
13
14 // 接收来自服务器的消息
15 BufferedReader in = new BufferedReader(new InputStreamReader(
16 client.getInputStream()));
17 String str = in.readLine();
18 // 关闭流
19 out.close();
20 in.close();
21 // 关闭Socket
22 client.close();
23 return str;
24 } catch (IOException e) {
25 e.printStackTrace();
26 }
27 return "";
28 }
29
30 public static void main(String[] args) {
31 SocketClientTCP client = new SocketClientTCP();
32 String str1 = client.sendMsg("127.0.0.1", 8823,"xiaoxi_1234567890A1234567!");
33 System.out.println("str1=====" + str1);
34 }
35 }
二、UDP实现方式
1、“服务端”实现方式
UDP的服务端主要是用到DatagramSocket、DatagramPacket类,通过new DatagramSocket(port)来创建一个socket,并且通过DatagramPacket来接收消息
代码如下:类SocketServerUDP:
1 private int port = 1114;
2 private DatagramSocket dataSocket;
3 private ExecutorService executorService;// 线程池
4 private final int POOL_SIZE = 100;// 单个CPU线程池大小
5
6 public SocketServerUDP() {
7 try {
8 dataSocket = new DatagramSocket(port);
9 executorService = Executors.newFixedThreadPool(Runtime.getRuntime()
10 .availableProcessors() * POOL_SIZE);
11 logger.info("端口号为" + port + "的服务器启动");
12 } catch (IOException e) {
13 e.printStackTrace();
14 }
15 }
16
17 public void service() {
18 System.out.println("socket初始化成功!");
19 logger.info("socket服务端初始化成功!");
20
21 while (true) {
22 try {
23 byte[] buff = new byte[128];// 传输消息不超过64字
24 DatagramPacket dataPacket = new DatagramPacket(buff, buff.length);
25 dataSocket.receive(dataPacket);// 等待接收来自客户端的数据包
26
27 executorService.execute(new UdpCallService(dataPacket));//接收到消息后执行具体的业务
28 } catch (Exception e) {
29 e.printStackTrace();
30 }
31 }
32 }
UDPCallService类主要作用是接收到消息后,来实现具体业务。
代码如下:
1 class UdpCallService implements Runnable {
2 Logger logger = Logger.getLogger(UdpCallService.class);
3 private DatagramPacket packet;
4 private DatagramSocket dataSocket;
5
6 public UdpCallService(DatagramPacket packet) {
7 try {
8 this.packet = packet;
9 // 创建本机可以端口的DatagramSocket
10 dataSocket = new DatagramSocket();
11 } catch (SocketException e) {
12 e.printStackTrace();
13 }
14 }
15
16 public void run() {
17 String str=new String(packet.getData());
18 System.out.println("接收到消息:"+str);
19 //返回数据给客户端
20 responeSocket("UDP消息返回:"+str);
21 }
22
23 //返回消息给客户端
24 public void responeSocket(String message){
25 // 构造响应数据包
26 byte[] response = message.toString().getBytes();
27 DatagramPacket dataPacket = new DatagramPacket(response, response.length, packet.getAddress(), packet.getPort());
28 try {// 发送
29 dataSocket.send(dataPacket);
30 } catch (IOException e) {
31 e.printStackTrace();
32 }
33 }
服务器启动方式:
1 public static void main(String[] args) {
2 new SocketServerUDP().service();
3 }
2、UDP客户端实现方式
UDP客户端的实现方式与"服务端"实现方式差不多,因为UDP本身就没有很严格的服务端和客户端定义。
代码如下:
1 public class SocketClientUDP {
2
3 private int PORT;
4
5 public SocketClientUDP(int PORT) {
6 this.PORT=PORT;
7 }
8
9 public String getMessage() {
10 String msg = "";
11 try {
12
13 String str = "hello world ";
14 DatagramSocket socket = new DatagramSocket();
15
16 // 发送UPD消息给服务端
17 DatagramPacket requestPacket = new DatagramPacket(str.getBytes(),
18 str.length(), InetAddress.getLocalHost(), PORT);
19 socket.send(requestPacket);
20
21 // 接收服务端返回的UDP消息
22 byte[] data = new byte[128];
23 DatagramPacket responsePacket = new DatagramPacket(data,data.length);
24 socket.receive(responsePacket);
25 msg = new String(responsePacket.getData(), 0,responsePacket.getLength());
26 socket.close();
27 } catch (UnknownHostException e) {
28 System.err.println("Exception: host could not be found");
29 } catch (Exception e) {
30 System.err.println("Exception: " + e);
31 e.printStackTrace();
32 }
33 return msg;
34 }
35
36 public static void main(String[] args){
37 SocketClientUDP clientUdp = new SocketClientUDP(1114);
38 String str1= clientUdp.getMessage();
39 System.out.println("str1====="+str1);
40 }
具体的JAVA文件下载地址: