server端:
package com.cskgnt.socket;
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.List;
public class TestSockServer {
public static ServerSocket serverSocket = null;
public static List<Socket> clientSocketList = new ArrayList<Socket>();
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(5888);
Accept a = new Accept(1);
Thread acceptThread = new Thread(a);
acceptThread.start();
// you can do sth else here, especially prepare test data etc.
while (a.getSocketList().size() != 1) {
waitto(1);
}
clientSocketList = a.getSocketList();
DataOutputStream dout = new DataOutputStream(clientSocketList
.get(0).getOutputStream());
for (int i = 0; i < 5; i++) {
dout.writeUTF("i'm server, cmd: " + i);
waitto(1);
}
dout.close();
waitto(10);
for (Socket s : clientSocketList) {
if (!s.isClosed())
s.close();
}
serverSocket.close();
if (!clientSocketList.isEmpty())
clientSocketList.clear();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void waitto(int second) {
try {
Thread.sleep(second * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Accept implements Runnable {
private int expectNum;
private List<Socket> socketList = new ArrayList<Socket>();
@SuppressWarnings("deprecation")
public Accept(int expectNum) {
if (expectNum == 0)
Thread.currentThread().stop();
this.expectNum = expectNum;
}
public void run() {
while (socketList.size() != expectNum) {
try {
socketList.add(TestSockServer.serverSocket.accept());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public List<Socket> getSocketList() {
return socketList;
}
public void setSocketList(List<Socket> socketList) {
this.socketList = socketList;
}
}
client端:
package com.cskgnt.socket;
import java.net.*;
import java.io.*;
public class TestSockClient {
@SuppressWarnings("deprecation")
public static void main(String[] args) {
try {
Socket socket = new Socket("10.10.10.10", 5888);
Thread comThread = new Thread(new Communicate(socket));
comThread.start();
waitto(7);
comThread.stop();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void waitto(int second) {
try {
Thread.sleep(second * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Communicate implements Runnable {
private Socket socket;
public Communicate(Socket socket) {
this.socket = socket;
System.out.println("start communicate with server...");
}
@SuppressWarnings("deprecation")
public void run() {
try {
DataInputStream din = new DataInputStream(socket.getInputStream());
String strFromClient = null;
while (true) {
try {
strFromClient = din.readUTF();
if (strFromClient != null) {
System.out.println(strFromClient);
}
// TestSockClient.waitto(1);
} catch (EOFException e) {
// e.printStackTrace();
} finally {
// din.close();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
Thread.currentThread().stop();
}
}
}
注:
1、由于accept是阻塞的,因此在server端用Accept线程监听连进来的client端socket,直到accept指定数目的client端之后,该线程自动退出。用clientSocketList保存accept的client端socket,本程序只接受一个;
2、在有client端连接进来之后,server端每隔1s发送一次消息,client端从输入流读取数据,并打印;
3、client端从输入流读取数据时,readUTP()可能会遇到读到数据末尾从而导致EOFException,这种异常是正常的,捕获到之后无需处理,继续读取下次消息即可;
4、client端连接成功7秒后程序退出,此时应已接收5条消息完毕;
5、server端发送完毕5条消息10秒后退出,此时client端socket应已断开连接,因此server端先后关闭接收的client端socket、server端socket;需要注意的是,此时clientSocketList仍然是有值的,如果此时需要再次开启server端socket来接收连接,应先将clientSocketList清空。