Java多執行緒局域網聊天室
- 局域網聊天室
- 1.TCP
- 2.套接字
- 3.C/S架構
- 4.多執行緒
- 5.服務器
- 客戶端
局域網聊天室
在學習了一個學期的java以后,覺得java真是博大精深,徹底放棄了因為c++而輕視java的心態,搞了一個多執行緒的聊天室,熟悉了一下服務器和客戶機的操作,
1.TCP
要實作局域網連接,就必須知道資訊傳輸的原理,
在局域網里面傳輸的資訊都是以包的形式,我使用的TCP包傳輸資料,TCP包里面封裝了IP報文,
下面這句話就是通過一個靜態IPV4協議的類得到一個服務器的IP地址,
address = InetAddress.getByName("192.168.43.86");
2.套接字
在TCP中得到了服務器的IP地址,但是光憑IP地址無法對具體應用進行鎖定,所以引入了套接字這個概念,埠號用來鎖定主機的行程,埠號一般取1024~49151,因為0 ~ 1023是熟知埠號,一般用于一些HTTP等等常用的埠,49152 ~ 65535是臨時埠號,也不能隨機占用,一般是程式運行程序中的臨時分配,
套接字=IP+埠號
這句話就是定義一個埠號9998和IP為192.168.43.86的套接字,
int port = 9998;
socket = new Socket(address,port);
3.C/S架構

從Java類的角度看,服務器和客戶端通過套接字連接抽象了一個連接,服務器通過建立自己的套接字埠并監聽有無客戶在此埠連接,實作資訊的讀取功能,客戶機通過服務器約定好的埠號,來對服務器進行傳輸資料,在服務器開啟后,運行客戶機,將與服務器進行三次握手建立TCP連接,然后在此連接的基礎上,實作客戶機與服務器的通信,
4.多執行緒
由于服務器可能同時服務多個物件,若是采用傳統的方法進行服務器連接,則會出現多個客戶機等待一個客戶機與服務器互動的現象,為了解決這個問題,采用多執行緒的方法,
用SuperSocket類繼承socket類并實作Runnable介面,實作多執行緒運行,
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.服務器
服務器的架構第三部分所示,代碼實作如下
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);
//實體化具有多執行緒功能的服務器專用socket類
//需要傳遞埠號作為初始化變數
SuperSocket socket_1 = new SuperSocket(9996);
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);
try {
while(true) {
//開啟執行緒
s1.start();
s2.start();
s3.start();
if(scan.next()=="123"){
//結束執行緒
break;
}
}
} finally {
try {
//關閉套接字
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 {
//初始服務器型套接字
serverSocket = new ServerSocket(port);
buffer = new byte[1024];
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
//等待埠連接
socket = serverSocket.accept();
//連接完成后創建輸入流
is = socket.getInputStream();
//讀取客戶端傳送資訊
int len = is.read(buffer);
String str = new String(buffer, 0, len);
System.out.println(str);
} catch (IOException e) {
e.printStackTrace();
}
}
}
客戶端
客戶端的架構第三部分所示,代碼實作如下
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 {
//得到本機IP地址
address = InetAddress.getByName("192.168.43.86");
//規定埠號,建立套接字
int port = 9998;
socket = new Socket(address,port);
//系結套接字的輸出流
os = socket.getOutputStream();
sca = new Scanner(System.in);
while(true) {
message = sca.next();
//寫入輸出流,在局域網中傳輸
os.write(message.getBytes());
}
} catch (UnknownHostException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}finally {
try {
//關閉埠號,關閉io流
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
搞定,雖然特別簡陋,但是也能實作局域網類的通信,如果需要復制代碼的,記得改一下服務器的IP地址,IP地址可以在cmd下用ipconfig命令查看,打算期末考試完了以后再加上GUI并把這個功能加到具有alpha剪枝演算法的AI六子棋對戰中去,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/287595.html
標籤:其他
上一篇:設計模式(單例、工廠)
下一篇:從零開始學架構-day05
