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

一个在服务器上运行的TCP通信转发服务器[Java]

2017-04-21 23:20 411 查看
刚刚写了一个简单的服务器转发功能,没什么难的,大概分享一下服务器的代码,以供有需要的人参考。

主要思路是这样的

建一个Map<String,Socket>存放着ip标示和相应的长连接Socket,需要转发时,从这个Map里获取相应的Socket,然后就可以转发了。

至于有关TCP的知识,看这里:http://blog.csdn.net/shenpibaipao/article/details/70176038

下面是服务器的代码:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
/*
*Create by Shenpibaipao
*http://blog.csdn.net/shenpibaipao
*/

public class AndroidServer implements Runnable{
private final int PORT=12345;
private ServerSocket serverSocket;
private Socket clientSocket;
private Map<String,Socket> onlineClientMap=new HashMap<String,Socket>();//存放已连接用户的ip,socket
public void run() {
System.out.println("Server Open\nWaiting for connect...");
try{
serverSocket=new ServerSocket(PORT);
}catch(Exception e){
e.printStackTrace();
return ;
}
while(true){
try{
clientSocket=serverSocket.accept();
onlineClientMap.put(clientSocket.getInetAddress().getHostAddress(),clientSocket);
System.out.println(clientSocket.getInetAddress().getHostAddress()+":"+clientSocket.getPort());
new Thread(new newTcpThread(clientSocket)).start();
}catch(Exception e){
e.printStackTrace();
System.out.println("Server Shutdown!");
}
}
}
private class newTcpThread implements Runnable{
private BufferedReader in = null;
private BufferedWriter out = null;
private Socket socket = null;
private byte b[];
public newTcpThread(Socket SOCKET){
socket=SOCKET;
}
//新开一个用于维护长连接的线程
public void run(){
System.out.println(socket.getPort()+" Has Connected.");
try{
in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));
while(true){
if(in.ready()){
String readIn=in.readLine();//这里会阻塞
String id=AnalyzeString(readIn,0);//获取目标ip
String msg=AnalyzeString(readIn,1);//获取发送方的消息

System.out.println("-:"+socket.getPort()+"-Send Msg:\n-:"+msg+"\n-:To:"+id);
if(msg.equals("Shutdown")){
//关闭服务器
System.out.println("Server Will Be Shutdown!");
System.exit(0);
}
try{
//转发给指定ip的用户
Socket resendSocket=onlineClientMap.get(id);
out = new BufferedWriter(new OutputStreamWriter(resendSocket.getOutputStream(),"UTF-8"));
out.write(msg+"\n");
out.flush();
}catch(Exception e){
System.out.println("Resend "+msg+" to["+id+"] Failed");
}
}
}
}catch(Exception e){
System.out.println("Recevie mag:["+socket.getPort()+"]Offline");
//e.printStackTrace();
}
}
}
//发送的消息格式为(ip,msg),下面这个方法用于将消息拆分
public String AnalyzeString(String STRING,int PARTNUM){
String str="";
int start=-1,end=STRING.indexOf(",");
for(int i=0;i<PARTNUM;i++){
start=STRING.indexOf(",",start+1);
end=STRING.indexOf(",",end+1);
}
if(end==-1)end=STRING.length();
str=STRING.substring(start+1,end);
return str;
}

public static void main(String arg[]){
new Thread(new AndroidServer()).start();
}
}
Android客户端的代码:

Runnable sendMessage=new Runnable() {
@Override
public void run() {
System.out.println("发送");
try{
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8"));
out.write(id.getText()+","+et.getText().toString()+"\n");// Send(  ip,msg  )
out.flush();//不加这个flush会怎样?
myUpdUIHandler.sendEmptyMessage(2);//更新UI
}catch (Exception e){
//e.printStackTrace();
System.out.println("发送失败");
}
}
};


关于中文编码的处理及发送时的处理,可以看这里:

http://blog.csdn.net/shenpibaipao/article/details/70236657

http://blog.csdn.net/shenpibaipao/article/details/70306744

为什么用Handler更新UI,看这里:

http://blog.csdn.net/shenpibaipao/article/details/70304702

关于Handler即安卓的消息循环机制的学习理解,看这里:

http://blog.csdn.net/shenpibaipao/article/details/70214927
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息