实现流程:
服务端
package com.jzj.socket;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
public abstract class SocketTransceiver implements Runnable {
protected Socket socket;
protected InetAddress addr;
protected DataInputStream in;
protected DataOutputStream out;
private boolean runFlag;
public SocketTransceiver(Socket socket) {
this.socket = socket;
this.addr = socket.getInetAddress();
}
public InetAddress getInetAddress() {
return addr;
}
public void start() {
runFlag = true;
new Thread(this).start();
}
public void stop() {
runFlag = false;
try {
socket.shutdownInput();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean send(String s) {
if (out != null) {
try {
out.writeUTF(s);
out.flush();
return true;
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
@Override
public void run() {
try {
in = new DataInputStream(this.socket.getInputStream());
out = new DataOutputStream(this.socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
runFlag = false;
}
while (runFlag) {
try {
final String s = in.readUTF();
this.onReceive(addr, s);
} catch (IOException e) {
// 连接被断开(被动)
runFlag = false;
}
}
// 断开连接
try {
in.close();
out.close();
socket.close();
in = null;
out = null;
socket = null;
} catch (IOException e) {
e.printStackTrace();
}
this.onDisconnect(addr);
}
public abstract void onReceive(InetAddress addr, String s);
public abstract void onDisconnect(InetAddress addr);
}
TCP连接工具类
package com.jzj.socket;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public abstract class TcpServer implements Runnable {
private int port;
private boolean runFlag;
private List<SocketTransceiver> clients = new ArrayList<SocketTransceiver>();
public TcpServer(int port) {
this.port = port;
}
public void start() {
runFlag = true;
new Thread(this).start();
}
public void stop() {
runFlag = false;
}
@Override
public void run() {
try {
final ServerSocket server = new ServerSocket(port);
while (runFlag) {
try {
final Socket socket = server.accept();
startClient(socket);
} catch (IOException e) {
// 接受客户端连接出错
e.printStackTrace();
this.onConnectFailed();
}
}
// 停止服务器,断开与每个客户端的连接
try {
for (SocketTransceiver client : clients) {
client.stop();
}
clients.clear();
server.close();
} catch (Exception e) {
e.printStackTrace();
}
} catch (IOException e) {
// ServerSocket对象创建出错,服务器启动失败
e.printStackTrace();
}
this.onServerStop();
}
private void startClient(final Socket socket) {
SocketTransceiver client = new SocketTransceiver(socket) {
@Override
public void onReceive(InetAddress addr, String s) {
TcpServer.this.onReceive(this, s);
}
@Override
public void onDisconnect(InetAddress addr) {
clients.remove(this);
TcpServer.this.onDisconnect(this);
}
};
client.start();
clients.add(client);
this.onConnect(client);
}
public abstract void onConnect(SocketTransceiver client);
public abstract void onConnectFailed();
public abstract void onReceive(SocketTransceiver client, String s);
public abstract void onDisconnect(SocketTransceiver client);
public abstract void onServerStop();
}
测试类:
package com.jzj.socket;
public class ClsMainServer {
public static void main(String[] args) {
int port = 1234;
TcpServer server = new TcpServer(port) {
@Override
public void onConnect(SocketTransceiver client) {
printInfo(client, "Connect");
}
@Override
public void onConnectFailed() {
System.out.println("Client Connect Failed");
}
@Override
public void onReceive(SocketTransceiver client, String s) {
printInfo(client, "Send Data: " + s);
if(s.equals("天王盖地虎")){
client.send("小鸡炖蘑菇"+"\n");
}else if(s.equals("有朋自远方来")){
client.send("必诛之"+"\n");
}else if(s.equals("芝麻开门")){
client.send("不开就不开"+"\n");
}else {
s = s.replace("吗","");
s = s.replace("?","!");
s = s.replace("?","!");
client.send(s+"\n");
}
}
@Override
public void onDisconnect(SocketTransceiver client) {
printInfo(client, "Disconnect");
}
@Override
public void onServerStop() {
System.out.println("--------Server Stopped--------");
}
};
System.out.println("--------Server Started--------");
server.start();
}
static void printInfo(SocketTransceiver st, String msg) {
System.out.println("Client " + st.getInetAddress().getHostAddress());
System.out.println(" " + msg);
}
}
安卓端;
package com.jzj.socket;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
public abstract class SocketTransceiver implements Runnable {
protected Socket socket;
protected InetAddress addr;
protected DataInputStream in;
protected DataOutputStream out;
private boolean runFlag;
public SocketTransceiver(Socket socket) {
this.socket = socket;
this.addr = socket.getInetAddress();
}
public InetAddress getInetAddress() {
return addr;
}
public void start() {
runFlag = true;
new Thread(this).start();
}
public void stop() {
runFlag = false;
try {
socket.shutdownInput();
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean send(String s) {
if (out != null) {
try {
out.writeUTF(s);
out.flush();
return true;
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
@Override
public void run() {
try {
in = new DataInputStream(this.socket.getInputStream());
out = new DataOutputStream(this.socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
runFlag = false;
}
while (runFlag) {
try {
final String s = in.readUTF();
this.onReceive(addr, s);
} catch (IOException e) {
// 连接被断开(被动)
runFlag = false;
}
}
// 断开连接
try {
in.close();
out.close();
socket.close();
in = null;
out = null;
socket = null;
} catch (IOException e) {
e.printStackTrace();
}
this.onDisconnect(addr);
}
public abstract void onReceive(InetAddress addr, String s);
public abstract void onDisconnect(InetAddress addr);
}
package com.jzj.socket;
import java.net.InetAddress;
import java.net.Socket;
public abstract class TcpClient implements Runnable {
private int port;
private String hostIP;
private boolean connect = false;
private SocketTransceiver transceiver;
public void connect(String hostIP, int port) {
this.hostIP = hostIP;
this.port = port;
new Thread(this).start();
}
@Override
public void run() {
try {
Socket socket = new Socket(hostIP, port);
transceiver = new SocketTransceiver(socket) {
@Override
public void onReceive(InetAddress addr, String s) {
TcpClient.this.onReceive(this, s);
}
@Override
public void onDisconnect(InetAddress addr) {
connect = false;
TcpClient.this.onDisconnect(this);
}
};
transceiver.start();
connect = true;
this.onConnect(transceiver);
} catch (Exception e) {
e.printStackTrace();
this.onConnectFailed();
}
}
public void disconnect() {
if (transceiver != null) {
transceiver.stop();
transceiver = null;
}
}
public boolean isConnected() {
return connect;
}
public SocketTransceiver getTransceiver() {
return isConnected() ? transceiver : null;
}
public abstract void onConnect(SocketTransceiver transceiver);
public abstract void onConnectFailed();
public abstract void onReceive(SocketTransceiver transceiver, String s);
public abstract void onDisconnect(SocketTransceiver transceiver);
}
package com.demo.main;
import com.jzj.socket.SocketTransceiver;
import com.jzj.socket.TcpClient;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
private Button bnConnect;
private TextView txReceive;
private EditText edIP, edPort, edData;
private Handler handler = new Handler(Looper.getMainLooper());
private TcpClient client = new TcpClient() {
@Override
public void onConnect(SocketTransceiver transceiver) {
refreshUI(true);
}
@Override
public void onDisconnect(SocketTransceiver transceiver) {
refreshUI(false);
}
@Override
public void onConnectFailed() {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "连接失败",
Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onReceive(SocketTransceiver transceiver, final String s) {
handler.post(new Runnable() {
@Override
public void run() {
txReceive.append(s);
}
});
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.findViewById(R.id.bn_send).setOnClickListener(this);
bnConnect = (Button) this.findViewById(R.id.bn_connect);
bnConnect.setOnClickListener(this);
edIP = (EditText) this.findViewById(R.id.ed_ip);
edPort = (EditText) this.findViewById(R.id.ed_port);
edData = (EditText) this.findViewById(R.id.ed_dat);
txReceive = (TextView) this.findViewById(R.id.tx_receive);
txReceive.setOnClickListener(this);
refreshUI(false);
}
@Override
public void onStop() {
client.disconnect();
super.onStop();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bn_connect:
connect();
break;
case R.id.bn_send:
sendStr();
break;
case R.id.tx_receive:
clear();
break;
}
}
private void refreshUI(final boolean isConnected) {
handler.post(new Runnable() {
@Override
public void run() {
edPort.setEnabled(!isConnected);
edIP.setEnabled(!isConnected);
bnConnect.setText(isConnected ? "断开" : "连接");
}
});
}
private void connect() {
if (client.isConnected()) {
// 断开连接
client.disconnect();
} else {
try {
String hostIP = edIP.getText().toString();
int port = Integer.parseInt(edPort.getText().toString());
client.connect(hostIP, port);
} catch (NumberFormatException e) {
Toast.makeText(this, "端口错误", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
private void sendStr() {
try {
String data = edData.getText().toString();
client.getTransceiver().send(data);
} catch (Exception e) {
e.printStackTrace();
}
}
private void clear() {
new AlertDialog.Builder(this).setTitle("确认清除?")
.setNegativeButton("取消", null)
.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
txReceive.setText("");
}
}).show();
}
}
服务端源码
安卓端源码