socket编程刚开始接触,做点小记录:
ps:在启动server后,重新运行时,会报错java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)at java.net.DualStackPlainSocketImpl.socketBind(DualStackPlainSocketImpl.java:106)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:190)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at cn.com.xutengfei.server.SocketTest.<init>(SocketTest.java:35)
at cn.com.xutengfei.server.SocketTest.main(SocketTest.java:30)
相当于端口已被占用未关闭,再次运行服务时自然会报错,在这里就遇到过的问题做点小记录而已
demo:
服务器端(eclipse):
public class SocketServer {
private static final int PORT = 1234;
private List<Socket> mList = new ArrayList<Socket>();
private ServerSocket server = null;
private ExecutorService mExecutorService = null;
private String receiveMsg;
private String sendMsg;
public static void main(String[] args) {
new SocketTest();
}
public SocketServer () {
try {
server = new ServerSocket(PORT);
mExecutorService = Executors.newCachedThreadPool();
System.out.println("服务器已启动...");
Socket client = null;
while (true) {
client = server.accept();
mList.add(client);
mExecutorService.execute(new Service(client));
}
} catch (Exception e) {
e.printStackTrace();
}
}
class Service implements Runnable {
private Socket socket;
private BufferedReader in = null;
private PrintWriter printWriter = null;
public Service(Socket socket) {
this.socket = socket;
try {
printWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8")), true);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream(), "UTF-8"));
printWriter.println("成功连接服务器" + "(服务器发送)");
System.out.println("成功连接服务器");
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
while (true) {
if ((receiveMsg = in.readLine()) != null) {
System.out.println("receiveMsg:" + receiveMsg);
if (receiveMsg.equals("0")) {
System.out.println("客户端请求断开连接");
printWriter.println("服务端断开连接" + "(服务器发送)");
mList.remove(socket);
in.close();
socket.close();
break;
} else {
sendMsg = "我已接收:" + receiveMsg + "(服务器发送)";
printWriter.println(sendMsg);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
客户端:
// Socket变量 private Socket socket; // 线程池 // 为了方便展示,此处直接采用线程池进行线程管理,而没有一个个开线程 private ExecutorService mThreadPool; // 输入流对象 InputStream is; // 输入流读取器对象 InputStreamReader isr; BufferedReader br; // 接收服务器发送过来的消息 String response; // 输出流对象 OutputStream outputStream;
// 初始化线程池 mThreadPool = Executors.newCachedThreadPool();
@Override public void onClick(View view) { switch (view.getId()) { case R.id.btn_connect: // 利用线程池直接开启一个线程 & 执行该线程 mThreadPool.execute(new Runnable() { @Override public void run() { try { // 创建Socket对象 & 指定服务端的IP 及 端口号 socket = new Socket(IP, 1234); // 判断客户端和服务器是否连接成功 System.out.println(socket.isConnected()); } catch (IOException e) { e.printStackTrace(); } } }); break; case R.id.btn_send: // 利用线程池直接开启一个线程 & 执行该线程 mThreadPool.execute(new Runnable() { @Override public void run() { try { // 步骤1:从Socket 获得输出流对象OutputStream // 该对象作用:发送数据 outputStream = socket.getOutputStream(); // 步骤2:写入需要发送的数据到输出流对象中 outputStream.write(("1" + "\n").getBytes("utf-8")); // 特别注意:数据的结尾加上换行符才可让服务器端的readline()停止阻塞 // 步骤3:发送数据到服务端 outputStream.flush(); } catch (IOException e) { e.printStackTrace(); } } }); break; case R.id.btn_receive: // 利用线程池直接开启一个线程 & 执行该线程 mThreadPool.execute(new Runnable() { @Override public void run() { try { // 步骤1:创建输入流对象InputStream is = socket.getInputStream(); // 步骤2:创建输入流读取器对象 并传入输入流对象 // 该对象作用:获取服务器返回的数据 isr = new InputStreamReader(is); br = new BufferedReader(isr); // 步骤3:通过输入流读取器对象 接收服务器发送过来的数据 response = br.readLine(); // 步骤4:通知主线程,将接收的消息显示到界面 Message msg = Message.obtain(); msg.what = 0; mMainHandler.sendMessage(msg); } catch (IOException e) { e.printStackTrace(); } } }); break; case R.id.btn_close: // 利用线程池直接开启一个线程 & 执行该线程 mThreadPool.execute(new Runnable() { @Override public void run() { try { //通知服务器断开连接 outputStream = socket.getOutputStream(); outputStream.write(("0" + "\n").getBytes("utf-8")); outputStream.flush(); } catch (IOException e) { e.printStackTrace(); } } }); break; } }在测试过程中,客户端主动断开连接后,再次连接服务端,发送数据时,服务端无法接收到数据1;发送断开连接请求,通知服务端来断开连接时,再次连接服务端,发送数据时,服务端正常接收到数据1