Java多線程局域網(wǎng)聊天室的實(shí)現(xiàn)
局域網(wǎng)聊天室
在學(xué)習(xí)了一個(gè)學(xué)期的java以后,覺(jué)得java真是博大精深,徹底放棄了因?yàn)閏++而輕視java的心態(tài),搞了一個(gè)多線程的聊天室,熟悉了一下服務(wù)器和客戶(hù)機(jī)的操作。
1.TCP
要實(shí)現(xiàn)局域網(wǎng)連接,就必須知道信息傳輸?shù)脑怼?br />
在局域網(wǎng)里面?zhèn)鬏數(shù)男畔⒍际且园男问?,我使用的TCP包傳輸數(shù)據(jù),TCP包里面封裝了IP報(bào)文。
下面這句話就是通過(guò)一個(gè)靜態(tài)IPV4協(xié)議的類(lèi)得到一個(gè)服務(wù)器的IP地址。
address = InetAddress.getByName("192.168.43.86");
2.套接字
在TCP中得到了服務(wù)器的IP地址,但是光憑IP地址無(wú)法對(duì)具體應(yīng)用進(jìn)行鎖定,所以引入了套接字這個(gè)概念。端口號(hào)用來(lái)鎖定主機(jī)的進(jìn)程。端口號(hào)一般取1024~49151,因?yàn)? ~ 1023是熟知端口號(hào),一般用于一些HTTP等等常用的端口,49152 ~ 65535是臨時(shí)端口號(hào),也不能隨機(jī)占用,一般是程序運(yùn)行過(guò)程中的臨時(shí)分配。
套接字=IP+端口號(hào)
這句話就是定義一個(gè)端口號(hào)9998和IP為192.168.43.86的套接字。
int port = 9998; socket = new Socket(address,port);
3.C/S架構(gòu)
從Java類(lèi)的角度看,服務(wù)器和客戶(hù)端通過(guò)套接字連接抽象了一個(gè)連接。服務(wù)器通過(guò)建立自己的套接字端口并監(jiān)聽(tīng)有無(wú)客戶(hù)在此端口連接,實(shí)現(xiàn)信息的讀取功能??蛻?hù)機(jī)通過(guò)服務(wù)器約定好的端口號(hào),來(lái)對(duì)服務(wù)器進(jìn)行傳輸數(shù)據(jù)。在服務(wù)器開(kāi)啟后,運(yùn)行客戶(hù)機(jī),將與服務(wù)器進(jìn)行三次握手建立TCP連接,然后在此連接的基礎(chǔ)上,實(shí)現(xiàn)客戶(hù)機(jī)與服務(wù)器的通信。
4.多線程
由于服務(wù)器可能同時(shí)服務(wù)多個(gè)對(duì)象,若是采用傳統(tǒng)的方法進(jìn)行服務(wù)器連接,則會(huì)出現(xiàn)多個(gè)客戶(hù)機(jī)等待一個(gè)客戶(hù)機(jī)與服務(wù)器交互的現(xiàn)象。為了解決這個(gè)問(wèn)題,采用多線程的方法。
用SuperSocket類(lèi)繼承socket類(lèi)并實(shí)現(xiàn)Runnable接口,實(shí)現(xiàn)多線程運(yùn)行。
class SuperSocket extends Socket implements Runnable
SuperSocket socket_1 = new SuperSocket(9999); SuperSocket socket_2 = new SuperSocket(9998); SuperSocket socket_3 = new SuperSocket(9997); Thread s1 = new Thread(socket_1); Thread s2 = new Thread(socket_2); Thread s3 = new Thread(socket_3);
5.服務(wù)器
服務(wù)器的架構(gòu)第三部分所示,代碼實(shí)現(xiàn)如下
package TCP; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class TCPserver2 { public static void main(String[] args) { Scanner scan = new Scanner(System.in); //實(shí)例化具有多線程功能的服務(wù)器專(zhuān)用socket類(lèi) //需要傳遞端口號(hào)作為初始化變量 SuperSocket socket_1 = new SuperSocket(9996); SuperSocket socket_2 = new SuperSocket(9998); SuperSocket socket_3 = new SuperSocket(9997); //建立三個(gè)子線程 Thread s1 = new Thread(socket_1); Thread s2 = new Thread(socket_2); Thread s3 = new Thread(socket_3); try { while(true) { //開(kāi)啟線程 s1.start(); s2.start(); s3.start(); if(scan.next()=="123"){ //結(jié)束線程 break; } } } finally { try { //關(guān)閉套接字 socket_1.close(); socket_2.close(); socket_3.close(); } catch (IOException e) { e.printStackTrace(); } } } } class SuperSocket extends Socket implements Runnable{ InputStream is; byte[] buffer; Socket socket=null; ServerSocket serverSocket=null; public SuperSocket(int port){ try { //初始服務(wù)器型套接字 serverSocket = new ServerSocket(port); buffer = new byte[1024]; } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { try { //等待端口連接 socket = serverSocket.accept(); //連接完成后創(chuàng)建輸入流 is = socket.getInputStream(); //讀取客戶(hù)端傳送信息 int len = is.read(buffer); String str = new String(buffer, 0, len); System.out.println(str); } catch (IOException e) { e.printStackTrace(); } } }
客戶(hù)端
客戶(hù)端的架構(gòu)第三部分所示,代碼實(shí)現(xiàn)如下
package TCP; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.Scanner; public class TCPclient { public static void main(String[] args) { InetAddress address=null; Socket socket=null; OutputStream os=null; String message=null; Scanner sca=null; try { //得到本機(jī)IP地址 address = InetAddress.getByName("192.168.43.86"); //規(guī)定端口號(hào),建立套接字 int port = 9998; socket = new Socket(address,port); //綁定套接字的輸出流 os = socket.getOutputStream(); sca = new Scanner(System.in); while(true) { message = sca.next(); //寫(xiě)入輸出流,在局域網(wǎng)中傳輸 os.write(message.getBytes()); } } catch (UnknownHostException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); }finally { try { //關(guān)閉端口號(hào),關(guān)閉io流 os.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
搞定,雖然特別簡(jiǎn)陋,但是也能實(shí)現(xiàn)局域網(wǎng)類(lèi)的通信。如果需要復(fù)制代碼的,記得改一下服務(wù)器的IP地址,IP地址可以在cmd下用ipconfig命令查看。打算期末考試完了以后再加上GUI并把這個(gè)功能加到具有alpha剪枝算法的AI六子棋對(duì)戰(zhàn)中去。
到此這篇關(guān)于Java多線程局域網(wǎng)聊天室的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java多線程局域網(wǎng)聊天室內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java實(shí)現(xiàn)局域網(wǎng)聊天室功能(私聊、群聊)
- Java實(shí)現(xiàn)局域網(wǎng)聊天小程序
- Java用局域網(wǎng)實(shí)現(xiàn)聊天室功能
- java?socket實(shí)現(xiàn)局域網(wǎng)聊天
- Java創(chuàng)建多線程局域網(wǎng)聊天室實(shí)例
- Java實(shí)現(xiàn)簡(jiǎn)單局域網(wǎng)聊天室
- java局域網(wǎng)聊天小程序
- java實(shí)現(xiàn)簡(jiǎn)易局域網(wǎng)聊天功能
- 基于java編寫(xiě)局域網(wǎng)多人聊天室
- java+socket實(shí)現(xiàn)簡(jiǎn)易局域網(wǎng)聊天室
相關(guān)文章
spring聲明式事務(wù)@Transactional底層工作原理
這篇文章主要為大家介紹分析spring聲明式事務(wù)@Transactional底層工作原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-02-02使用jenkins+maven+git發(fā)布jar包過(guò)程詳解
這篇文章主要介紹了使用jenkins+maven+git發(fā)布jar包過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07java中synchronized關(guān)鍵字的3種寫(xiě)法實(shí)例
synchronized是Java中的關(guān)鍵字,是一種同步鎖,下面這篇文章主要給大家介紹了關(guān)于java中synchronized關(guān)鍵字的3種寫(xiě)法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-11-11SpringBoot集成QQ第三方登陸的實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot集成QQ第三方登陸的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11基于mybatis注解動(dòng)態(tài)sql中foreach工具的方法
這篇文章主要介紹了mybatis注解動(dòng)態(tài)sql中foreach工具方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11