目录
概述
基于TCP的Socket通信
搭建工程
编码
SocketServerTCP类
SocketThreadTCP
SocketClientTCP
演示
概述
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.net.ServerSocket;
import java.net.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.net.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.net.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通信,是已经成功了。
如果大家还想继续测试,就不要关停服务端的程序,再次启动客户端程序就可以了。
|