先上代碼,這個是部署在公網服務器的代碼,必須要有固定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();
}
}
上圖為服務器部署在本機,客戶端訪問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微信等的原理(功能增加中)-創新互聯
文章起源:http://vcdvsql.cn/article16/ddhjdg.html
成都網站建設公司_創新互聯,為您提供營銷型網站建設、云服務器、微信公眾號、全網營銷推廣、手機網站建設、自適應網站
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯