1. 程式人生 > >群聊實現(tcp和多執行緒)

群聊實現(tcp和多執行緒)

服務端程式碼

package com.cyj.tcp.chat2;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * 建立伺服器,可以接收多個客戶端
 * @author Chyjrily
 *
 */
public class Server {
	
	private List<Channel> all = new ArrayList<Channel>(); //通過容器,管理管理其他的管道,轉發時只需遍歷容器
	
	public static void main(String[] args) throws IOException {
	
	new Server().start(); //呼叫下面的方法,呼叫靜態方法
    
}
	
	public void start() throws IOException {
	    ServerSocket server = new ServerSocket(2500);  
		
	    while(true) {
			Socket client = server.accept();  
			Channel ch = new Channel(client); //建立一條通道
			all.add(ch); //將自己加入容器
			new Thread(ch).start(); //啟動分配管道的多執行緒
		}	
	}
	       

	
   //每個客戶端分配一條道路
   class Channel implements Runnable{
	   
	   private DataInputStream dis;
	   private DataOutputStream dos;
	   private boolean isRunning = true;
	   
	   public Channel(Socket client) throws IOException{
		   try {
			dis = new DataInputStream(client.getInputStream());
			dos =new DataOutputStream(client.getOutputStream());
		   
		} catch (IOException e) {
			dis.close();
			dos.close();
			isRunning = false;
		 }
	   }
	   
	   
	   //讀取資料
	   private String receive() {
		   String msg = ""; 
		   try {
			msg = dis.readUTF();
		} catch (IOException e) {
			all.remove(this);//管道出現異常,移除出容器
		} 
		   return msg;
	   }
	   
	   //傳送資料
	   private void send(String msg){
		   if(null==msg || msg.equals("")) {
			   return;
		   }
		   try {
			dos.writeUTF(msg);
			dos.flush();
		} catch (IOException e) {
			all.remove(this);//管道出現異常,移除出容器
		}  
	   }
	   
	   
	   //轉發內容給其他的客戶端 
	   private void sendOthers() {
		   String msg = receive();
		   
		   //遍歷容器
		   for(Channel other:all) {
			   if(other == this) {
				   continue;
			   }
			   //轉發
			   other.send(msg);
		   }
	   }
	   
	   public void run() {
		   while(isRunning) {
			   sendOthers();
		   }
	   }
   }
}

客戶端程式碼

package com.cyj.tcp.chat2;

import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 客戶端可以傳送和接收資料,且相互獨立
 * 資料的接收和傳送不能夠有先後順序
 * @author Chyjrily
 *
 */
public class Client {

	public static void main(String[] args) throws UnknownHostException, IOException {
		Socket client = new Socket("DESKTOP-BEUJ3C4",2500);
		
		new Thread(new Send(client)).start();     //呼叫傳送資料的多執行緒
		new Thread(new Receive(client)).start();  //呼叫接收資料的多執行緒

	}
	
}

接收資料建立的多執行緒

package com.cyj.tcp.chat2;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

/**
 * 接收執行緒
 * @author Chyjrily
 *
 */
public class Receive implements Runnable {
	
	private boolean isRunning = true;
	
	//管道輸入流 
	private DataInputStream dis;
	
	public Receive() {
			
	}
	
	public Receive(Socket client) throws IOException {
		try {
			dis = new DataInputStream(client.getInputStream());
		} catch (IOException e) {
			isRunning = false;
			dis.close();
		}	
	}
	
	public String receive() throws IOException {
		while(true) {
			String msg = "沒有接收到資料";
			dis.readUTF();
			return msg;
		}
	}
	
	public void run(){
		while(isRunning) {
			try {
				System.out.println(receive());
			} catch (IOException e) {
				e.printStackTrace();
				System.out.println("接收失敗");
			}
		}
	}
	
}

傳送資料建立的多執行緒

package com.cyj.tcp.chat2;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * 通過多執行緒,將客戶端的資料的傳送與資料的接收想一致
 * @author Chyjrily
 *
 */
public class Send implements Runnable {

	//控制檯輸入流
	private BufferedReader console;
	
	//管道輸出流
	private DataOutputStream dos;
	
	//管道是否能正常執行的標識
	private boolean isRunning = true;
	
	public Send(){
		console = new BufferedReader(new InputStreamReader(System.in));
		
	}
	
	public Send(Socket client) throws IOException{ //通過接收資料,將管道傳過來
		this();
		try {
			dos = new DataOutputStream(client.getOutputStream());
		} catch (IOException e) {
			isRunning = false; //管道是一切傳輸的基礎,如果不執行,直接終止程式
			dos.close();
			console.close();
		}
	}
	
	//從控制檯接收資料
	private String getMsg() throws IOException{
		return console.readLine();
	}
	
	public void send() throws IOException {
		String msg = getMsg();
		if(null != msg) {
			dos.writeUTF(msg);
			dos.flush();
		}
	}
	
	public void run() {
		 while(isRunning) { //是否執行的標誌
			try {
				send();
			} catch (IOException e) {
				e.printStackTrace();
				System.out.println("伺服器多執行緒啟動失敗");
			} 
		 }
	}
}

相關推薦

實現tcp執行

服務端程式碼 package com.cyj.tcp.chat2; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import ja

iOS應用開發基礎基礎知識資料儲存執行

本文可能涉及很多零碎的知識點,其中包括iOS應用開發的相關基礎知識。以後會針對每個條目在進行深入研究,這裡只是先做一個相關知識的概述總結。 iOS的資料儲存 大多數iOS程式其功能總結為:提供一套介面,幫助使用者管理特定資料。在這個過程中,不同物件各司其

ucontext實現的使用者級執行框架2搶先式執行

#include "uthread.h"#include <assert.h>#include <stdlib.h>#include <time.h>ucontext_t Scheduler::ucontext;char Scheduler::stack[4096];u

python爬蟲:爬取貓眼電影分數的處理執行

爬取用的庫是requests和beautifulsoup,程式碼編寫不難,主要是個別的細節處理需要注意 1、電影得分的處理 右鍵審查元素,我們看到分數的整數部分和小數部分是分開的,在beautifulsoup中,我們可以用(.strings或者.stripped_stri

Android連線伺服器,從伺服器獲取資料,以及從伺服器下載檔案單,執行

首先需要在Eclipse中建立一個伺服器,在其中存入要下載的檔案,具體可參考之前的伺服器篇。 ScollView可以上下滑動 另外還有,android中的網路連線與之前java中可以通用,可以參照之前伺服器客戶端通訊篇。 新增的許可權

Qt:Qt實現Winsock網路程式設計—TCP服務端客戶端通訊執行

Qt實現Winsock網路程式設計—TCP服務端和客戶端通訊(多執行緒) 前言 感覺Winsock網路程式設計的api其實和Linux下網路程式設計的api非常像,其實和其他程式語言的網路程式設計都差不太多。博主用Qt實現的,當然不想用黑視窗唄,有介面可以看到,由於GUI程式設計

再說說單例模式執行靜態內部類實現

靜態內部類: package thread.singleton; public class StaticInnerClassSingleton { private static class Singleton{ private static Singleton si

Linux網路程式設計【三】:TCP伺服器程序執行http訪問版本

為了讓伺服器同時接受多個客戶端訪問,所以需要多程序或者多執行緒 多程序版本: #include<unistd.h> #include<stdio.h> #include<stdlib.h> #include<sys/types.h

tcp/ip 執行伺服器端的實現參考tcp/ip網路程式設計

執行緒的切換比程序快的多,因為它不需要切換資料區和堆 共享資料區和堆可以用來交換資訊 一、執行緒的建立 pthread_create()函式 #include<pthread.h> int prthread_create(pthread * thread,c

C#.net同步非同步SOCKET通訊執行總結5tcp傳送接受的程式碼

基於TCP協議的傳送和接收端 TCP協議的接收端 using System.Net.Sockets ; //使用到TcpListen類 using System.Threading ; //使用到執行緒 using System.IO ; //使用到StreamReader類 int port = 800

WPF利用Interactive Data Display實現示波器C#執行WPF執行

2018.8.7(已實現) 首先,今天還沒有實現示波器,專案中需要這個功能,在探索中有了一點進展,先記錄下來。 實現的chart控制元件,能夠相應滑輪、滑鼠拖動、放大縮小,很適合作為示波器的背景。 關於Interactive Data Display的引用,可以考慮

python學習之使用UDP執行實現一個聊天室

        在學習UDP的時候,想著試一試能不能搞一個命令視窗的udp聊天工具,因為udp的廣播機制,所以就想著乾脆直接搞一個群聊的吧。不過最後搞來搞去,命令視窗下使用多執行緒,沒有做出什麼好看整潔的“圖形化”介面,湊合著用吧,畢竟是一個練習的學習型的小玩意。有時間把列印

併發伺服器的實現程序、執行...

一、多程序實現併發伺服器 程式碼如下:multiprocess_server.c /* ============================================================================ Name : TCPServ

實現客戶端寫入字串,在服務端翻轉後返回執行

實現客戶端寫入字串,在服務端翻轉後返回 服務端: package network.tcp; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import

高併發的實現非同步化+快取+執行

一年前,本人有幸負責公司核心專案的優化。隨著公司業務的增長,專案處理量也越來越大。 一次818大促甚至導致一臺伺服器滿負荷運作。於是,高併發改造被提上行程。 乾貨開始: 技術實現上有三個重點:非同步化(一般使用mq)、快取(一般使用redis)、多執行緒 一個功能併發量上大的提升,是需要業務

C#學習篇之基礎回顧16----- 程序執行

程序 程序(Process)是Windows系統的一個基本概念。一個應用程式在作業系統中執行被視為一個程序,程序可以包括一個或多個執行緒。 程序之間是相對獨立的,一個程序無法訪問另一個程序的資料(除非使用分散式計算方式),一個程序執行失敗也不會影響另一個程序。 執行緒

程序執行簡單tcp聊天程式

如果需要一個服務端可以連線多個客戶端,並同時與多個(不超多listen第二個引數及最大同時併發數)客戶端通訊,可以利用多程序即建立子程序,子程序來完成服務端的接受和傳送資料;也可以建立多個執行緒。對於tcp一些介面具體使用可以檢視這篇部落格:https://bl

網路程式設計實驗四——利用程序執行實現伺服器端的併發處理

一、實驗目的 1.在TCP檔案傳輸程式碼的基礎上,利用多程序實現伺服器端的併發處理。  2.利用多執行緒實現伺服器端的併發處理。 二、實驗原理 併發的面向連線伺服器演算法: 主1、建立套接字並將其繫結到所提供服務的熟知地址上。讓該套接字保持為無連線的。 主2、將

Java執行實現程序與執行的概念、Java繼承Thread類實現執行、Java實現Runnable介面實現執行、Thread與Runnable的區別、實現Callable介面實現執行

1 程序與執行緒 1.1 程序與執行緒的概念 什麼是程序?   程序: 作業系統中一個程式的執行週期。(比如我們想要在電腦上登入QQ,從雙擊qq按鈕---->關閉qq這個過程就是一個程序)   多程序: 同一時刻跑多個程式。   在DOS(磁碟作業系統時

網路程式設計——4.利用程序執行實現伺服器端的併發處理

一、實驗要求     在TCP檔案傳輸程式碼的基礎上,利用單執行緒程序併發模型和多執行緒併發模型實現伺服器端的併發處理。 二、實驗分析     多執行緒與多程序相比,使用多執行緒相比多程序有以下兩個優點:更高的效率和共享儲存器,效率的提高源於上下文切換次數的減少。