189 8069 5689

用java实现的端口转发,QQ微信等的原理(功能增加中)-创新互联

先上代码,这个是部署在公网服务器的代码,必须要有固定IP地址。各个客户端必须能用服务器IP连接。下面的代码只能接受显示来自客户端的信息,还不能转发

创新互联建站坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站设计、做网站、成都外贸网站建设公司、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的九江网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!

其实原理很简单:各个客户端通过Socket 与服务器连接上,服务器监听与客户端连接的端口,通过软件操作,把收到的各个端口信息分别发给对应的端口。这个场景就像QQ ,微信  ,vpn ,代理,隧道,文件共享等等,你只要为一个客户端写某种请求功能后,其他的客户端就可以通过端口享受这种功能

1.利用线程在一个程序中监控两个端口(服务器代码)

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;


public class Main {

        public static void main(String[] args) throws IOException {
            ServerSocket ss=new ServerSocket(3000);     //理论上可以开无数多个端口
            ServerSocket ss1=new ServerSocket(3001);

                Thread t1 = new T1(ss);       //经验证,while内 不能有Thread循环,会报错
                Thread t2 = new T2(ss1);
                t1.start();
                t2.start();
        }
        static class T1 extends Thread{
            ServerSocket ssi;
            T1(ServerSocket ssi) {       //T1构造函数,为T1赋初值
                this.ssi = ssi;
            }
            public void run() {

                try {
                    while(true) {
                        Socket sc = ssi.accept();      //经验证,ServerSocket 不能用在线程中,否则回报端口占用的错误
                        InputStream is = sc.getInputStream();

                        byte[] b = is.readAllBytes();
                        System.out.println(new String(b));
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }


        static class T2 extends Thread{
            ServerSocket ssi1;
            T2(ServerSocket ssi1) {
                this.ssi1 = ssi1;
            }
            public void run() {
                try {
                    while(true) {
                        Socket sc1 = ssi1.accept();
                        InputStream is1 = sc1.getInputStream();
                        byte[] b1 = is1.readAllBytes();
                        System.out.println(new String(b1));
                    }
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

            }
        }


}

客户端可以没有外网固定IP,如在192.168号段内,只要能连接上服务器就可以了。通过服务器的软件操作,在各个端口间调用信息,客户端之间就可以通信了,就如QQ一样,T1,T2之间可以互发信息。

客户端代码:下面的客户端代码为socket短连接,现只能发送信息,如要收到服务器的信息,必须和服务器长连接,就像QQ一直在线一样。所以要去掉os.close(),再加一个循环等待。一直监控服务器方的数据输入。为客户端分配端口号,就相当于QQ注册。QQ掉线,就相当于socket关闭。客户端之间断开。

import java.net.Socket;
import java.io.*;
public class Con1{
        public static void main(String[] args) throws IOException{
                Socket sc=new Socket("127.0.0.1",3001);
                OutputStream os=sc.getOutputStream();
                os.write("hello1".getBytes());
                System.out.println("ok");
                os.close();
}
}

f082feb5e8084db8921f7de045e4e737.png

上图为服务器部署在本机,客户端访问127.0.0.1  的显示结果

服务器内端口信息转发的思路:为每一个端口配一个接收标志位,输出标志位,接收存储区,输出存储区。如果是多端口,再配一个目标端口位。服务器根据标志位的状态,和目标端口号,把相应端口号的信息互换,完成端口转发。

2.socket长连接:客户端与服务器之间双向传输数据代码

客户端代码:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class Con {

    public static void main(String[] args) throws IOException {
        String data;
        while(true) {
            Scanner scan = new Scanner(System.in);

            String sin = scan.nextLine();
            data =sin;
            Socket sc = new Socket("114.132.48.228", 3000);
            OutputStream os = sc.getOutputStream();
            os.write((data+'\n').getBytes(StandardCharsets.UTF_8));  //数据结尾一定要加\n,经验证
            System.out.println("send over");

            InputStream is=sc.getInputStream();
            String s="";
            int t=is.read();
            while((char)t!='\n'){       //通过\n来判断输入完成
                s=s+(char)t;
                t=is.read();
            }
            System.out.println(s);
        }
    }
}

服务器端代码:

import java.nio.charset.StandardCharsets;
import java.io.InputStream;
import java.io.*;
public class Server1 {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(3000);
        while(true) {

        Socket sc=ss.accept();

        InputStream is=sc.getInputStream();
        String s="";
        int t=is.read();
        while((char)t!='\n'){
            s=s+(char)t;
            t=is.read();
        }
        System.out.println(s);

        OutputStream os=sc.getOutputStream();
        os.write("server send:hello\n".getBytes());
        System.out.println("server:send over");
//      sc.close();
        }
}
}

经验证,这里不能用InputStream  is=sc.getInputStream();

               byte[] b=is.readAllBytes();

只能用原始的int t=is.read();

特别注意:客户端和服务器端传输数据末尾必须加'\n',作为判断符号,当然,也可以换成其他符号如:^  ,~  等非常用符号,甚至^~两个符号连用,但要改变while判断语句。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


新闻标题:用java实现的端口转发,QQ微信等的原理(功能增加中)-创新互联
分享URL:http://cdxtjz.cn/article/ddhjdg.html

其他资讯