基于测试驱动的Socket入门实例(代码的具体功能可以看我的程序中的注释,不理解的可以短信我)
先看Server的代码:
package socketStudy;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.log4j.Logger;
/**
* 类ServerSocket.java的实现描述:
*/
public class Server {
private static final Logger log = Logger.getLogger("actionLog");
private ServerSocket server;
private List<String> list = new ArrayList<String>();
public Server(int port) throws IOException{
server = new ServerSocket(port);
}
/**
* 启动server的监听程序,当server关闭的时候停止监听
*
* @throws IOException
*/
public void listen() throws IOException {
Socket client;
String temp;
BufferedReader br = null;
//如果当前server已经手动关闭,则终止监听
while (!server.isClosed()) {
// 每当检测到套接字,就获得一个socket链接
// 这个方法在连接传入之前,一直阻塞
client = server.accept();
//注意这里只需要获取一次client的输入流即可
br = new BufferedReader(new InputStreamReader(client.getInputStream()));
temp = br.readLine();
while (temp != null) {
list.add(temp);
temp = br.readLine();
}
//这里立即关闭了client,事实上可以建立个timeOut时间
if(client.isClosed()){
client.close();
}
br.close();
}
}
/**
* 每次都返回当前的套接字的传入内容<br/>
* 在返回后清空当前的list
*
* @return List<String>
*/
public synchronized List<String> getList() {
List<String> newArrayList=new ArrayList<String>(Arrays.asList(new String[list.size()]));
Collections.copy(newArrayList, list);
list.clear();
return newArrayList;
}
/**
* 返回当前server是否成功绑定上指定接口<br/>
* true表示成功绑定,false则表示没有绑定
*
* @return boolean
*/
public boolean isBound() {
return server.isBound();
}
/**
* 关闭当前server
*/
public void close() {
if (server != null) {
try {
server.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
}
@Override
public String toString() {
return this.server.toString();
}
}
再看client的程序示例;
package socketStudy;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import org.apache.log4j.Logger;
/**
* 类Client.java的实现描述:
*/
public class Client {
private static final Logger log = Logger.getLogger("actionLog");
private Socket client;
private PrintWriter out;
public Client(String serverIp, int port) throws UnknownHostException, IOException{
client = new Socket(serverIp, port);
out = new PrintWriter(client.getOutputStream(), true);
}
/**
* 向server发送消息
*
* @param message
*/
public void send(String message) {
out.println(message);
}
/**
* 关闭当前client
*/
public void close() {
if (client != null) {
try {
client.close();
} catch (IOException e) {
log.error(e.getMessage(), e);
}
}
if (out != null) {
out.close();
}
}
}
最后看我们的测试代码(基于testng)
package test;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import org.testng.Assert;
import org.testng.annotations.Test;
import socketStudy.Client;
import socketStudy.Server;
/**
* 类TestSocket.java的实现描述:
*/
public class TestSocket {
private Server server;
private static final int port=8733;
@SuppressWarnings("static-access")
@Test
public void testSocket() throws IOException,InterruptedException{
//这里需要单独起个线程来在client发送消息前启动server的监听程序
Thread serverThread=new Thread() {
@Override
public void run() {
try{
server = new Server(port);
server.listen();
}catch(IOException e){
throw new RuntimeException(e);
}
}
};
serverThread.start();
//这里通过线程不断的睡眠来等待server的监听程序启动成功
while(true){
if(server==null||!server.isBound()){
Thread.currentThread().sleep(1000);
}else{
break;
}
}
Client client = new Client("127.0.0.1", port);
client.send("test");
client.send("joking");
client.close();
server.close();
//获取当前client发送的消息
List<String> actualList = server.getList();
List<String> expectedList = Arrays.asList("test", "joking");
Assert.assertEquals(actualList, expectedList);
}
}