网上找到不少例子都是必须客户端先发送一个消息,服务端再回复一条消息。这样的方式对于服务端想主动发送消息给客户端就很不方便了。
研究了一下,发现主要是因为BufferedReader的时候用readline方法会将线程阻塞在那儿,换用DataInputStream和DataOutputStream就可以实现了。
Server端代码:
import java.net.*;
import java.io.*;
import test.Configuration;
/**
* @author ChenYi
*
*/
public class TCPServer {
public TCPServer() {
try {
ServerSocket server = new ServerSocket();
server.bind(new InetSocketAddress(Configuration.TCPIP,
Configuration.TCPPort));
while (true) {
// transfer location change Single User or Multi User
TCPServerThread tct = new TCPServerThread(server.accept());
tct.start();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
if (args.length == 2) {
try {
Configuration.TCPIP = args[0];
Configuration.TCPPort = Integer.parseInt(args[1]);
} catch (Exception ex) {
System.exit(1);
}
}
new TCPServer();
}
}
import java.net.*;
import java.io.*;
/**
* @author ChenYi
*
*/
public class TCPServerThread extends Thread {
Socket client;
volatile static int num = 0;
public TCPServerThread(Socket c) {
this.client = c;
System.out.println(client.getInetAddress().getHostAddress() + ":"
+ client.getPort());
}
@Override
public void run() {
int i = ++num;
System.out.println("Thread " + i + " is starting");
try {
DataInputStream in = new DataInputStream(client.getInputStream());
DataOutputStream out = new DataOutputStream(
client.getOutputStream());
BufferedReader wt = new BufferedReader(new InputStreamReader(
System.in));
// Mutil User but can parallel
while (true) {
if (in.available() > 0) {
String str = in.readUTF();
System.out.println(str);
out.writeUTF(str + " has receive....");
out.flush();
if (str.equals("end") || (null == str)) {
break;
}
} else {
if (wt.ready()) {
String str = wt.readLine();
out.writeUTF(str);
out.flush();
}else{
try {
client.sendUrgentData(0xFF);
Thread.sleep(100);
} catch (Exception ex) {
ex.printStackTrace();
break;
}
}
}
}
client.close();
} catch (Exception ex) {
ex.printStackTrace();
} finally {
System.out.println("Thread " + i++ + " is ending");
}
}
}
客户端代码:
import java.net.*;
import java.io.*;
import test.Configuration;
/**
* @author ChenYi
*
*/
public class TCPClient {
static Socket socket;
public static void main(String[] args) throws Exception {
if (args.length == 2) {
try {
Configuration.TCPIP = args[0];
Configuration.TCPPort = Integer.parseInt(args[1]);
} catch (Exception ex) {
System.exit(1);
}
}
socket = new Socket();
socket.connect(new InetSocketAddress(Configuration.TCPIP,
Configuration.TCPPort), 2000);
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
BufferedReader wt = new BufferedReader(new InputStreamReader(System.in));
while (true) {
if (wt.ready()) {
String str = wt.readLine();
out.writeUTF(str);
out.flush();
if (str.equals("end")) {
break;
}
} else {
try {
socket.sendUrgentData(0xFF);
Thread.sleep(100);
} catch (Exception ex) {
ex.printStackTrace();
break;
}
}
if (in.available() > 0)
System.out.println(in.readUTF());
}
socket.close();
}
}
实现了可以同时接受多个客户端的连接请求,客户端/服务端随时都可以从命令行输入并发送字符串,一端关闭的时候另一端会抛出异常(可以增加异常的处理)。