最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

javaTCP雙向通信

2022-09-07 09:50 作者:虛云幻仙  | 我要投稿

/**
* 實(shí)現(xiàn)TCP雙向通信
* 需要能夠同時(shí)完成接收和發(fā)送,將這兩個(gè)操作分給兩個(gè)線程來處理
*/


public class TCPTwoWayCommunication {
}
class Status1{
? ?//反映連接狀態(tài)
? ?private boolean over;
? ?//直接使用默認(rèn)的無參構(gòu)造器,新建連接時(shí)默認(rèn)沒有結(jié)束notOver,當(dāng)需要結(jié)束時(shí)setOver(true)

? ?public boolean isOver() {
? ? ? ?return over;
? ?}

? ?public void setOver(boolean over) {
? ? ? ?this.over = over;
? ?}
}
class Sender1 extends Thread{
? ?//發(fā)送數(shù)據(jù)的線程
? ?PrintWriter pw;
? ?Scanner sc;
? ?final Status1 status;
? ?public Sender1(PrintWriter pw,Scanner sc,Status1 status) {
? ? ? ?this.pw = pw;
? ? ? ?this.sc = sc;
? ? ? ?this.status = status;
? ?}

? ?@Override
? ?public void run() {
? ? ? ?while (true){
? ? ? ? ? ?String message = sc.nextLine();
? ? ? ? ? ?if (status.isOver())break;
? ? ? ? ? ?//判斷通信是否已經(jīng)結(jié)束
? ? ? ? ? ?pw.println(message);
? ? ? ? ? ?if ("exit".equalsIgnoreCase(message)){
? ? ? ? ? ? ? ?//己方想要結(jié)束通信時(shí)輸入exit
? ? ? ? ? ? ? ?status.setOver(true);
? ? ? ? ? ? ? ?break;
? ? ? ? ? ?}
? ? ? ?}
? ?}
}
class Receiver1 extends Thread{
? ?//接收數(shù)據(jù)的線程
? ?BufferedReader br;
? ?PrintWriter pw;
? ?Scanner sc;
? ?final Status1 status;

? ?public Receiver1(BufferedReader br, PrintWriter pw,Scanner sc,Status1 status) {
? ? ? ?this.br = br;
? ? ? ?this.pw = pw;
? ? ? ?this.sc = sc;
? ? ? ?this.status = status;
? ?}

? ?@Override
? ?public void run() {
? ? ? ?Sender1 s1 = new Sender1(pw, sc,status);
? ? ? ?s1.start();
? ? ? ?do {
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?String message = br.readLine();
? ? ? ? ? ? ? ?//.readLine()會(huì)阻塞,直到收到對方的內(nèi)容,如果對方結(jié)束通信會(huì)返回null
? ? ? ? ? ? ? ?if (status.isOver())break;
? ? ? ? ? ? ? ?//如果是己方輸入exit結(jié)束通信,這時(shí)status.isOver()=true,
? ? ? ? ? ? ? ?// 但己方的exit只是將Sender線程結(jié)束,并且發(fā)送"exit"給對方Receiver線程使對方Receiver線程關(guān)閉,雖然己方設(shè)置了status但己方br.readLine()還在阻塞,所以需要對方Receiver線程接收到exit后隨便發(fā)些什么內(nèi)容來解除己方的阻塞才能判定status


? ? ? ? ? ? ? ?if ("exit".equalsIgnoreCase(message)){
? ? ? ? ? ? ? ? ? ?//這個(gè)if是接收到對方的"exit",這時(shí)對方的Sender線程已經(jīng)結(jié)束,但Receiver線程還在.readLine()阻塞,所以需要發(fā)送任意消息以解除對方阻塞
? ? ? ? ? ? ? ? ? ?pw.println("");
? ? ? ? ? ? ? ? ? ?//這里也可以通過關(guān)閉輸出流來解決,輸出流關(guān)閉后,對方.readLine()返回null,或者對方.read()返回-1,也會(huì)解除阻塞
? ? ? ? ? ? ? ? ? ?status.setOver(true);
? ? ? ? ? ? ? ? ? ?System.out.print("對方結(jié)束了通信,輸入任意內(nèi)容退出: ");
? ? ? ? ? ? ? ? ? ?//這里由于己方Sender線程還在等待用戶輸入而阻塞,所以提示用戶輸入任何內(nèi)容來解除阻塞、判定status來結(jié)束線程
? ? ? ? ? ? ? ? ? ?break;
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?if (message==null)break;
? ? ? ? ? ? ? ?//這個(gè)if應(yīng)該不會(huì)生效,用作保險(xiǎn),當(dāng)一方結(jié)束通信/關(guān)閉Socket后另一方.readLine()會(huì)返回null即輸入流讀到末尾了,如果是.read()則會(huì)返回-1,而如果對方?jīng)]有輸入內(nèi)容直接回車會(huì)接收到空字符串""而不是null
? ? ? ? ? ? ? ?System.out.println("收到信息: "+message);
? ? ? ? ? ?} catch (IOException e) {
? ? ? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ? ? ?}
? ? ? ?}while (true);
? ? ? ?synchronized (status) {
? ? ? ? ? ?//需要關(guān)閉的對象由主線程創(chuàng)建、關(guān)閉,主線程在創(chuàng)建Receiver線程后.wait()阻塞
? ? ? ? ? ?status.notify();
? ? ? ? ? ?//喚醒主線程
? ? ? ?}
? ?}
}
class Server1{
? ?public static void main(String[] args) {
? ? ? ?try(ServerSocket ss = new ServerSocket(8888);
? ? ? ? ? ?Socket socket = ss.accept();
? ? ? ? ? ?BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
? ? ? ? ? ?Scanner sc = new Scanner(System.in);
? ? ? ? ? ?PrintWriter pw = new PrintWriter(socket.getOutputStream(),true)
? ? ? ?) {
? ? ? ? ? ?System.out.println(socket.getPort());
? ? ? ? ? ?//客戶端的端口為52065
? ? ? ? ? ?Status1 status = new Status1();
? ? ? ? ? ?System.out.println("服務(wù)端已啟動(dòng),已連接客戶端,請輸入需要發(fā)送的內(nèi)容,輸入exit結(jié)束通信");
? ? ? ? ? ?Receiver1 r1 = new Receiver1(br,pw,sc,status);
? ? ? ? ? ?r1.start();
? ? ? ? ? ?synchronized(status){
? ? ? ? ? ? ? ?if (r1.isAlive()){
? ? ? ? ? ? ? ? ? ?status.wait();
? ? ? ? ? ? ? ? ? ?//對象鎖為status,main先執(zhí)行同步代碼,執(zhí)行到r1.isAlive()=true后.wait()阻塞釋放status對象鎖,等待r1結(jié)束循環(huán)后執(zhí)行同步代碼喚醒main
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ?} catch (IOException | InterruptedException e) {
? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ?}

? ? ? ?System.out.println("通信結(jié)束");
? ?}
}

class Client1{
? ?public static void main(String[] args) {
? ? ? ?Scanner sc = new Scanner(System.in);
? ? ? ?Socket socket = null;
? ? ? ?PrintWriter pw=null;
? ? ? ?BufferedReader br = null;
? ? ? ?try {
? ? ? ? ? ?socket = new Socket("127.0.0.1",8888);
? ? ? ? ? ?pw = new PrintWriter(socket.getOutputStream(),true);
? ? ? ? ? ?br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
? ? ? ? ? ?System.out.println("已連接服務(wù)端,請輸入需要發(fā)送的內(nèi)容,輸入exit結(jié)束通信");
? ? ? ? ? ?Status1 status = new Status1();
? ? ? ? ? ?Receiver1 r1 = new Receiver1(br,pw,sc,status);
? ? ? ? ? ?r1.start();
? ? ? ? ? ?synchronized(status){
? ? ? ? ? ? ? ?if (r1.isAlive()){
? ? ? ? ? ? ? ? ? ?status.wait();
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ?} catch (IOException | InterruptedException e) {
? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ?} finally {
? ? ? ? ? ?System.out.println("執(zhí)行finally,關(guān)閉順序遵循后進(jìn)先出");
? ? ? ? ? ?if (br != null) {
? ? ? ? ? ? ? ?try {
? ? ? ? ? ? ? ? ? ?br.close();
? ? ? ? ? ? ? ?} catch (IOException e) {
? ? ? ? ? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ? ? ?System.out.println("關(guān)閉br");
? ? ? ? ? ?if (pw != null) {
? ? ? ? ? ? ? ?pw.close();
? ? ? ? ? ?}
? ? ? ? ? ?System.out.println("關(guān)閉pw");
? ? ? ? ? ?if (socket != null) {
? ? ? ? ? ? ? ?try {
? ? ? ? ? ? ? ? ? ?socket.close();
? ? ? ? ? ? ? ?} catch (IOException e) {
? ? ? ? ? ? ? ? ? ?throw new RuntimeException(e);
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ? ? ?System.out.println("關(guān)閉socket");
? ? ? ? ? ?sc.close();
? ? ? ? ? ?//當(dāng)發(fā)送線程因?yàn)閳?zhí)行sc.nextLine()等待用戶輸入而阻塞時(shí),無法使用sc.close()關(guān)閉,而sc之前的其他流、對象都已經(jīng)關(guān)閉,這就導(dǎo)致主線程等待關(guān)閉sc而阻塞,當(dāng)用戶輸入任意內(nèi)容回車后,發(fā)送線程向下執(zhí)行,如果調(diào)用pw.println(),因?yàn)閜w已經(jīng)關(guān)閉了就會(huì)拋出異常,所以在sc.nextLine()和pw.println()之間進(jìn)行status判定
? ? ? ? ? ?//將發(fā)送線程設(shè)定為守護(hù)線程的思路是錯(cuò)的,守護(hù)線程需要等所有用戶線程結(jié)束后才會(huì)停止,而主線程會(huì)因?yàn)閟c.close()阻塞無法向下執(zhí)行導(dǎo)致用戶線程未結(jié)束。主線程等守護(hù)線程結(jié)束后再關(guān)sc,守護(hù)線程等主線程結(jié)束才停止。
? ? ? ? ? ?//這里如果是己方提出exit,那么Sender線程和Receiver線程都結(jié)束了,sc正常close。如果是對方提出exit,己方因?yàn)镽eceiver線程結(jié)束喚醒主線程,向下關(guān)閉流、對象,執(zhí)行到sc.close()時(shí)等待用戶輸入任何內(nèi)容以退出。等待用戶輸入內(nèi)容后Sender線程安全結(jié)束后,主線程執(zhí)行close并安全退出

? ? ? ? ? ?System.out.println("關(guān)閉sc");
? ? ? ?}

? ? ? ?System.out.println("通信結(jié)束");

? ?}
}

javaTCP雙向通信的評論 (共 條)

分享到微博請遵守國家法律
晴隆县| 喀喇| 清徐县| 海原县| 花莲县| 砀山县| 辽宁省| 东台市| 正镶白旗| 双鸭山市| 黄浦区| 彭泽县| 余江县| 沁水县| 安化县| 花莲市| 桂东县| 海丰县| 大竹县| 青岛市| 沽源县| 得荣县| 兰西县| 本溪| 临安市| 瑞安市| 临高县| 乌拉特后旗| 武隆县| 宕昌县| 新田县| 温宿县| 靖江市| 台前县| 和硕县| 固阳县| 沁水县| 涪陵区| 新泰市| 怀化市| 宜州市|