1. 程式人生 > >真正去理解Socket通訊方式,手卡與基站連線方式到底是怎麼樣的?

真正去理解Socket通訊方式,手卡與基站連線方式到底是怎麼樣的?

在2018/10/25-2018/11/08專案試執行期間,存在著某種奇怪的現象,現象描述如下:

 工人下井時候,基站總是漏了個別人的訊號;

工人下班出井口的時候,大約7個人中總有一兩個人的手卡訊號,基站是收不到訊號的;

注意:只有一個手卡的訊號超過10分鐘沒有收到而且最後的位置是在井口位置消失的,才能把這個人從大螢幕上消失;

這個現象導致的結果是:

這個人明明已經下班了,但是由於井口基站收不到資訊,最後接受訊號的基站並非是井口的基站,不滿足在大螢幕上消除的條件,這個人的名字會一直顯示在大螢幕上;

當一個人的名字一天都顯示在大螢幕上的時候,人們會認為這個人在井下是出現了礦難或者是危險的事情,這是不好的徵兆。人們會下去救援;如果這個人沒事的話,大螢幕上一直顯示,會造成虛報報警;

造成如上情況的原因究竟是什麼?

猜想1、是工人路過基站訊號覆蓋的區域的時候由於走的太快了,再加上是一群人一起上下班,基站來不及讀取所有人的訊號?

猜想2、這些個別人的手卡有問題?

猜想3、手卡每隔10s傳送一次資料到基站,如果6個手卡,基站接受的資料至少1分鐘,一個成年人的速度,走出訊號覆蓋的區域只需要40s就可以了;

猜想4、由於訊號覆蓋的區域有強弱之分如同磁場一樣,在訊號強的時候,接受速度很快,在弱的情況下,只有幾個人可以連線上基站傳送訊號,工人下班及時在基站訊號範圍好的情況到訊號不好的情況?

猜想5、還是程式存在的問題?因為之前18秒可以接受20個手卡資訊,現在怎麼9個人的訊號都接受不了?是程式哪裡出了問題麼?

上述猜想暴露的問題主要是:

與基站連線時間太短有關、訊號強弱分佈不均勻、手卡本身連線基站方式有關、程式有問題;

以下是我的實驗過程:

基站與手卡怎麼建立連線、傳送資料如下:

 

 

 

專案試執行過程中,總會出現,耗時20s、15s、8s、甚至超過1min的現象

 

 

 

如上的條件是:

19個基站,開啟多執行緒,總共4個人;按理說同一個手卡傳送資料是10s一次,多執行緒的開啟是互不影響的,怎麼會出現一個手卡都是間隔20s或者幾分鐘都沒有資料傳送的情況?

不知道是什麼阻擋了通訊的訊號接收??

多執行緒雖然同時執行,但也爭奪先後,所以是不是誰先就先執行誰的任務,也存在排隊,雖然是互不干擾的?

 

 

 

 

 試執行的程式碼與如上測試的程式碼是一樣的

之前測試,只是看全部接受手卡訊號需要多長時間,但是從來沒有把程式執行3-5分鐘,來看看結果是不是跟預想的一樣,

試執行期間的程式碼:

//這個讀取資料,如果輸入流裡沒有資料,就重新建立連線
	public static void Port(ServerSocket server){
		Socket socket1 = null;
		Date dd=new Date();
		SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String ss=sim.format(dd);
		System.out.println("連線之前:"+ss);
		try {
			socket1 = server.accept();
			System.out.println("連線之後:"+ss);//延遲1秒執行 目的是為了使一次讀取輸入流裡面的資料更多一點
			Thread.sleep(2000);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
				
		try {
			while(true){
				InputStream in=socket1.getInputStream();
				byte[] buf = new byte[1024];
				int len = -1;
				len = in.read(buf);
				if(len>7){			
					ThreadReaders.read(buf,len);
				}else{
					Port(server);	
				}
					
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		

這個是修改過後的程式碼:

2018-11-9再次修改部落格,這個程式碼不正確,執行以後,雖然接受速度很快,而且沒有大於2秒的間隔,但是都是同樣的編號,這個部落格的結論的科學性有待後期考證.......

//這個讀取資料,如果輸入流裡沒有資料,就重新建立連線
	public static void Port(ServerSocket server){
		Socket socket1 = null;
		Date dd=new Date();
		SimpleDateFormat sim=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String ss=sim.format(dd);
		System.out.println("連線之前:"+ss);
		try {
			socket1 = server.accept();
			System.out.println("連線之後:"+ss);
			//延遲1秒執行 目的是為了使一次讀取輸入流裡面的資料更多一點
				Thread.sleep(2000);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
						try {
			
				InputStream in=socket1.getInputStream();
				byte[] buf = new byte[1024];
				int len = -1;
				len = in.read(buf);
				while(len>7){		
//2018-11-9修改部落格 這個程式不對,len>7是恆成立的,因為一開始只有接受資料 len就一定大於7,而且一直成立,只能獲取一個編號的值	
					ThreadReader.read(buf,len);
				}
					Port(server);

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
}

當把這兩個程式在同一個條件下面試運行同樣的時間以後,結果如下:

 

 

 2018-11-9 再次修改這個部落格,當專案試執行一天以後,發現一個致命的缺陷,就是這張表,仔細發現全是一個number=0256的,這個修改過的程式是錯誤的;因此這個結論是有待考證的。

 

 

 

 

 

 

 

 

 以上實驗報告證明:

試執行期間出現的問題與訊號強弱、與手卡、與時間長短、與連線方式都無關,是程式出了問題;