先上代碼,這個(gè)是部署在公網(wǎng)服務(wù)器的代碼,必須要有固定IP地址。各個(gè)客戶端必須能用服務(wù)器IP連接。下面的代碼只能接受顯示來(lái)自客戶端的信息,還不能轉(zhuǎn)發(fā)
創(chuàng)新互聯(lián)建站堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、成都外貿(mào)網(wǎng)站建設(shè)公司、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的九江網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!其實(shí)原理很簡(jiǎn)單:各個(gè)客戶端通過(guò)Socket 與服務(wù)器連接上,服務(wù)器監(jiān)聽(tīng)與客戶端連接的端口,通過(guò)軟件操作,把收到的各個(gè)端口信息分別發(fā)給對(duì)應(yīng)的端口。這個(gè)場(chǎng)景就像QQ ,微信? ,vpn ,代理,隧道,文件共享等等,你只要為一個(gè)客戶端寫(xiě)某種請(qǐng)求功能后,其他的客戶端就可以通過(guò)端口享受這種功能
1.利用線程在一個(gè)程序中監(jiān)控兩個(gè)端口(服務(wù)器代碼)
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); //理論上可以開(kāi)無(wú)數(shù)多個(gè)端口
ServerSocket ss1=new ServerSocket(3001);
Thread t1 = new T1(ss); //經(jīng)驗(yàn)證,while內(nèi) 不能有Thread循環(huán),會(huì)報(bào)錯(cuò)
Thread t2 = new T2(ss1);
t1.start();
t2.start();
}
static class T1 extends Thread{
ServerSocket ssi;
T1(ServerSocket ssi) { //T1構(gòu)造函數(shù),為T(mén)1賦初值
this.ssi = ssi;
}
public void run() {
try {
while(true) {
Socket sc = ssi.accept(); //經(jīng)驗(yàn)證,ServerSocket 不能用在線程中,否則回報(bào)端口占用的錯(cuò)誤
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);
}
}
}
}
客戶端可以沒(méi)有外網(wǎng)固定IP,如在192.168號(hào)段內(nèi),只要能連接上服務(wù)器就可以了。通過(guò)服務(wù)器的軟件操作,在各個(gè)端口間調(diào)用信息,客戶端之間就可以通信了,就如QQ一樣,T1,T2之間可以互發(fā)信息。
客戶端代碼:下面的客戶端代碼為socket短連接,現(xiàn)只能發(fā)送信息,如要收到服務(wù)器的信息,必須和服務(wù)器長(zhǎng)連接,就像QQ一直在線一樣。所以要去掉os.close(),再加一個(gè)循環(huán)等待。一直監(jiān)控服務(wù)器方的數(shù)據(jù)輸入。為客戶端分配端口號(hào),就相當(dāng)于QQ注冊(cè)。QQ掉線,就相當(dāng)于socket關(guān)閉??蛻舳酥g斷開(kāi)。
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();
}
}
上圖為服務(wù)器部署在本機(jī),客戶端訪問(wèn)127.0.0.1? 的顯示結(jié)果
服務(wù)器內(nèi)端口信息轉(zhuǎn)發(fā)的思路:為每一個(gè)端口配一個(gè)接收標(biāo)志位,輸出標(biāo)志位,接收存儲(chǔ)區(qū),輸出存儲(chǔ)區(qū)。如果是多端口,再配一個(gè)目標(biāo)端口位。服務(wù)器根據(jù)標(biāo)志位的狀態(tài),和目標(biāo)端口號(hào),把相應(yīng)端口號(hào)的信息互換,完成端口轉(zhuǎn)發(fā)。
2.socket長(zhǎng)連接:客戶端與服務(wù)器之間雙向傳輸數(shù)據(jù)代碼
客戶端代碼:
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)); //數(shù)據(jù)結(jié)尾一定要加\n,經(jīng)驗(yàn)證
System.out.println("send over");
InputStream is=sc.getInputStream();
String s="";
int t=is.read();
while((char)t!='\n'){ //通過(guò)\n來(lái)判斷輸入完成
s=s+(char)t;
t=is.read();
}
System.out.println(s);
}
}
}
服務(wù)器端代碼:
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();
}
}
}
經(jīng)驗(yàn)證,這里不能用InputStream? is=sc.getInputStream();
?????????????? byte[] b=is.readAllBytes();
只能用原始的int t=is.read();
特別注意:客戶端和服務(wù)器端傳輸數(shù)據(jù)末尾必須加'\n',作為判斷符號(hào),當(dāng)然,也可以換成其他符號(hào)如:^? ,~? 等非常用符號(hào),甚至^~兩個(gè)符號(hào)連用,但要改變while判斷語(yǔ)句。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
網(wǎng)頁(yè)題目:用java實(shí)現(xiàn)的端口轉(zhuǎn)發(fā),QQ微信等的原理(功能增加中)-創(chuàng)新互聯(lián)
文章起源:http://bm7419.com/article16/ddhjdg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷(xiāo)型網(wǎng)站建設(shè)、云服務(wù)器、微信公眾號(hào)、全網(wǎng)營(yíng)銷(xiāo)推廣、手機(jī)網(wǎng)站建設(shè)、自適應(yīng)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容