TCPServer
原理:创建服务器套接字,绑定到指定的端口,等待客户端连接。接受客户端连接,创建线程处理连接。
代码实现:
public class TCPServer {
private int port;
private boolean isFinished;
private ServerSocket serverSocket;
private ArrayList<SocketThread> socketThreads;
public TCPServer(int port) {
this.port = port;
socketThreads = new ArrayList<>();
}
public void start() {
isFinished = false;
try {
//创建服务器套接字,绑定到指定的端口
serverSocket = new ServerSocket(port);
//等待客户端连接
while (!isFinished) {
Socket socket = serverSocket.accept();//接受连接
//创建线程处理连接
SocketThread socketThread = new SocketThread(socket);
socketThreads.add(socketThread);
socketThread.start();
}
} catch (IOException e) {
isFinished = true;
}
}
public void stop() {
isFinished = true;
for (SocketThread socketThread : socketThreads) {
socketThread.interrupt();
socketThread.close();
}
try {
if (serverSocket != null) {
serverSocket.close();
serverSocket = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
private class SocketThread extends Thread {
private Socket socket;
private InputStream in;
private OutputStream out;
SocketThread(Socket socket) {
this.socket = socket;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (!isInterrupted()) {
if (in == null) {
return;
}
try {
int available = in.available();
if (available > 0) {
byte[] buffer = new byte[available];
int size = in.read(buffer);
if (size > 0) {
String data = new String(buffer,0,size);
System.out.println("TCPClient say :" + data);
//返回结果给TcpClient
String response = "TCPServer response:" + data;
out.write(response.getBytes());
out.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
void close() {
try {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
if (socket != null) {
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
调用例子:
//TCPServer开启
tcpServer = new TCPServer(port);
new Thread(()-> tcpServer.start()).start();
//TCPServer停止
tcpServer.stop();
TCPClient
原理:创建一个连接的套接字,将此套接字连接到指定IP和端口的服务器,双方成功建立连接之后,就可以进行数据交互了。
代码实现:
public abstract class TCPClient {
private String ip;
private int port;
private Socket mSocket;
private SocketAddress mSocketAddress;
private OutputStream mOutputStream;
private InputStream mInputStream;
private ReadThread mReadThread;
private boolean _isConnected = false;
public TCPClient(String ip, int port) {
this.ip = ip;
this.port = port;
}
public void connect() {
try {
this.mSocket = new Socket();
this.mSocket.setKeepAlive(true);
this.mSocketAddress = new InetSocketAddress(ip, port);
this.mSocket.connect( mSocketAddress, 3000);// 设置连接超时时间为3秒
this.mOutputStream = mSocket.getOutputStream();
this.mInputStream = mSocket.getInputStream();
this.mReadThread = new TCPClient.ReadThread();
this.mReadThread.start();
this._isConnected = true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void close() {
if (this.mReadThread != null) {
this.mReadThread.interrupt();
}
if (this.mSocket != null) {
try {
this.mSocket.close();
this.mSocket = null;
} catch (IOException e) {
e.printStackTrace();
}
}
this._isConnected = false;
}
public boolean isConnected() {
return this._isConnected;
}
public void send(byte[] bOutArray) {
try {
this.mOutputStream.write(bOutArray);
} catch (IOException e) {
e.printStackTrace();
}
}
protected abstract void onDataReceive(byte[] bytes, int size);
private class ReadThread extends Thread {
@Override
public void run() {
super.run();
while (!isInterrupted()) {
try {
if (TCPClient.this.mInputStream == null) {
return;
}
int available = TCPClient.this.mInputStream.available();
if (available > 0) {
byte[] buffer = new byte[available];
int size = TCPClient.this.mInputStream.read(buffer);
if (size > 0) {
onDataReceive(buffer, size);
}
} else {
Thread.sleep(50);
}
} catch (Throwable e) {
System.out.println(e.getMessage());
return;
}
}
}
}
}
调用例子:
tcpClient = new TCPClient(ip, port) {
@Override
protected void onDataReceive(byte[] bytes, int size) {
String content = "TCPServer say :" + new String(bytes, 0, size);
System.out.println(content);
}
};
tcpClient.connect();//连接TCPServer
if (tcpClient.isConnected()) {
//发送数据
String outContent = "TCPClient say hello";
tcpClient.send(outContent.getBytes());
}
//关闭连接
tcpClient.close();