您的位置:首页 > 理论基础 > 计算机网络

Java通过 Socket 实现 TCP服务端(一个实例)

2017-05-11 16:13 405 查看
Java Socket简介

TCPServer代码实例

1 Java Socket简介

  所谓socket 通常也称作”套接字“,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过”套接字”向网络发出请求或者应答网络请求。Socket和ServerSocket类库位于Java.NET包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。

2 TCPServer代码实例

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* TCP服务器端,单例模式
* @author xiang
*
*/
public class TCPServer implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(TCPServer.class);
//成员变量/
private static TCPServer serverInstance;
private static Map<String, SocketThread> socketMaps = new HashMap<String,SocketThread>();        //每个客户端连接时都会新建一个SocketThread与之对应 private static ServerSocket serverSocket; //服务器套接字
private static int serPort = 9999; //服务器端口号
private static boolean flag; //服务器状态标志
private static final int BUFFER_SIZE = 512; //数据接收字符数组大小

//构造函数/
private TCPServer() {

}

/**
* 获取实例
* @return TCPServer实例serverIns
4000
tance
*/
public static TCPServer getServerInstance(){
if(serverInstance==null)
serverInstance = new TCPServer();
return serverInstance;
}

/**
* 开启服务器
* @throws IOException
*/
public void openTCPServer() throws IOException{ if(serverSocket==null || serverSocket.isClosed()){
serverSocket = new ServerSocket(serPort);
flag = true;
}
}

/**
* 关闭服务器
* @throws IOException
*/
public void closeTCPServer() throws IOException{
flag = false; if(serverSocket!=null)
serverSocket.close();
/*for (Map.Entry<String, SocketThread> entry : socketMaps.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
} */
for (SocketThread value : socketMaps.values())
value.closeConnect();
socketMaps.clear();
}

/**
* 服务器向客户端发送数据
* @param bytes[]:待发送的字符数组
* @param key 客户端的key,为空或""时表示数据群发
* @throws IOException
*/
public void sendMessage(String key,byte[] msgBytes){
if(key==null||key.equals("")){
for (SocketThread value : socketMaps.values())
value.sendMassage(msgBytes);
}else{
SocketThread thread = socketMaps.get(key);
if(thread!=null)
thread.sendMassage(msgBytes);
}
}

/**
* 服务器向客户端发送数据
* @param key 客户端的key,为空或""时表示数据群发
* @param msgStr:待发送的字符串
* @throws IOException
*/
public void sendMessage(String key,String msgStr){ byte[] sendByte = msgStr.getBytes();
if(key==null||key.equals("")){
for (SocketThread value : socketMaps.values())
value.sendMassage(sendByte);
}else{
SocketThread thread = socketMaps.get(key);
if(thread!=null)
thread.sendMassage(sendByte);
}
}

@Override
public void run() {
logger.info("服务器线程已经启动"); while(true){
try {
while(flag){
logger.info("服务器线程在监听状态中");
Socket socket = serverSocket.accept();
String key = socket.getRemoteSocketAddress().toString();
SocketThread thread = new SocketThread(socket,key);
thread.start();
socketMaps.put(key, thread);
logger.info("有客户端连接:"+key);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

/**
* 处理连接后的数据接收请求内部类
* @author xiang
*
*/
private class SocketThread extends Thread{
private Socket socket;
private String key;
private OutputStream out;
private InputStream in;

//构造函数
public SocketThread(Socket socket,String key) {
this.socket = socket;
this.key = key;
}

/**
* 发送数据
* @param bytes
* @throws IOException
*/
public void sendMassage(byte[] bytes){
try {
if(out==null)
out = socket.getOutputStream();
out.write(bytes);
} catch (Exception e) {
e.printStackTrace();
try {
closeConnect();
} catch (IOException e1) {
e1.printStackTrace();
}
socketMaps.remove(key);
}
}

/**
* 关闭连接,释放资源
* @throws IOException
*/
public void closeConnect() throws IOException{
if(out!=null) out.close();
if(in!=null) in.close();
if(socket!=null && socket.isConnected()) socket.close();
}

@Override
public void run() {
byte[] receivBuf = new byte[BUFFER_SIZE];
int recvMsgSize;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
while ((recvMsgSize = in.read(receivBuf)) != -1) {
String receivedData = new String(receivBuf, 0, recvMsgSize);
System.out.println("Reverve form[port" + socket.getPort() + "]:" + receivedData);
System.out.println("Now the size of socketMaps is" + socketMaps.size());
/**************************************************************
*
* 接收数据后的处理过程
*
**************************************************************/
}
// response to client
byte[] sendByte = "The Server has received".getBytes();
// out.write(sendByte, 0, sendByte.length);
out.write(sendByte);
System.out.println("To Cliect[port:" + socket.getPort() + "] 回复客户端的消息发送成功");
closeConnect();
socketMaps.remove(key);
} catch (Exception e) {
e.printStackTrace();
try {
closeConnect();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}

//////////////
public int getport(){
return socket.getPort();
}
}
//. end SocketThread
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: