c语言tcp多线程聊天室,66 网络编程(五)——TCP多线程实现多人聊天室
思路
客戶端讀寫各一個類,可以使內部類,實現Runnable。讀寫類都與服務器端建立連接,一個收,一個發。
客戶端實現接收和轉發。多線程實現每個客戶端的連接(使與各客戶端的連接獨立)。
服務器端中創建一個公共緩沖池,用于存放消息。通過服務器中的轉發方法轉發給個客戶端。
客戶端?代碼
package _20191218;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
*多人聊天室,客戶端,實時發送接收數據,要實現多線程
*/
public class TCPMultipleChatClient {
public static void main(String[] args) {
System.out.println("-------局域網聊天室-----------");
Scanner scan1 = new Scanner(System.in);
System.out.print("請輸入您的昵稱:");
String username = scan1.nextLine();
String address = "176.195.108.53";//服務器地址
int port = 6788;//服務器程序端口
Socket client = null;
try {
client = new Socket(address,port);
System.out.println("成功登入,可以開始聊天了!");
System.out.println("------------------------");
} catch (UnknownHostException e) {
System.err.println("服務器連接失敗");
} catch (IOException e) {
System.err.println("服務器連接失敗");
}
/**
* 啟動接收器與發送器
*/
new Thread(new Sender(client),username).start();
new Thread(new Receiver(client)).start();
}
}
//發送器:實現Runnable
class Sender implements Runnable{
private boolean flag = true;//服務器存活為 true
//輸出流
private DataOutputStream dos;
//構造器:初始化
public Sender(Socket client) {
try {
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
System.err.println("服務器未開啟,連接失敗");
}
}
public void sendMessage() {
Scanner scan = new Scanner(System.in);
String message = scan.nextLine();
try {
dos.writeUTF(Thread.currentThread().getName()+":"+message);
dos.flush();
} catch (IOException e) {
System.err.println("Sender:服務器關閉");
flag = false;
}
}
public void run() {
while(flag) {
sendMessage();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//接收器:實現Runnable
class Receiver implements Runnable{
private boolean flag = true;//服務器存活為 true
//輸入流
private DataInputStream dis;
public Receiver(Socket client) {
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
//讀取消息
public void readMessage() {
try {
System.out.println(dis.readUTF());
} catch (IOException e) {
System.err.println("Reciver:服務器關閉");
flag =false;
}
}
public void run() {
while(flag) {
readMessage();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//}
服務器端?代碼
package _20191218;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
* 多人聊天室,服務端,實時轉發數據
*/
public class TCPMultipleChatServer {
public static void main(String[] args) {
System.out.println("服務端開啟");
//創建服務器端
ServerSocket server = null;
try {
server = new ServerSocket(6788);//服務器端口
} catch (IOException e) {
e.printStackTrace();
}
//容器
Container container = new Container();
//循環監聽
while(true) {
//阻塞監聽連接請求
try {
Socket client = server.accept();
System.out.println("一位用戶成功連接");
container.doCount();
//開啟接收器
new Thread(new Receiver(client,container)).start();
//開啟轉發器
new Thread(new Transmit(client,container)).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
static class Container{
//StringBuffer wrap = new StringBuffer();
static int userCount = 0;//當前用戶量
private int now = 0;//已轉發量
private String[] strs = new String[1024];//消息隊列
private int i = 0;//消息計數器
public void add(String message) {
strs[i]=message;
i++;
}
public static void doCount() {//用戶量加一
userCount++;
}
public void subUserCount() {//用戶量減一
userCount--;
}
public void reset() {
if(now == userCount) {
strs = new String[1024];
now = 0;
}
}
}
static class Receiver implements Runnable{
private boolean flag = true;
private Container container;
private DataInputStream dis;
public Receiver(Socket client,Container container) {
this.container = container;
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
//讀取消息
public void readMessage() {
try {
//存入容器
String str = "";
if(!(str = dis.readUTF()).equals("")) {
container.add(str);
}
} catch (IOException e) {
flag = false;
System.err.println("Read:用戶已離開會話");
container.subUserCount();
}
}
public void run() {
while(flag) {
readMessage();
}
}
}
//轉發
static class Transmit implements Runnable{
private boolean flag = true;
private Container container;
private DataOutputStream dos;
public Transmit(Socket client, Container container) {
this.container = container;
try {
this.dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
flag = false;
System.err.println("Transmit:用戶已離開會話");
}
}
public void run() {
while(flag) {
transmit();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void transmit() {
for(String str : container.strs) {
try {
if(str==null) {
continue;
}
System.out.println("已轉發消息:"+str);
container.now++;
dos.writeUTF(str);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
container.reset();//轉發完后清空
}
}
}
演示
服務器端運行一個,客戶端運行多個。
總結
以上是生活随笔為你收集整理的c语言tcp多线程聊天室,66 网络编程(五)——TCP多线程实现多人聊天室的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Na小工具(电脑)
- 下一篇: 四年级计算机课程表制作教案,四年级上信息