你是怎么判定他是亂了呢?你是根據(jù)log打印的情饑早況?

創(chuàng)新互聯(lián)建站專注于企業(yè)成都全網(wǎng)營銷推廣、網(wǎng)站重做改版、河北網(wǎng)站定制設計、自適應品牌網(wǎng)站建設、成都h5網(wǎng)站建設、成都做商城網(wǎng)站、集團公司官網(wǎng)建設、成都外貿(mào)網(wǎng)站建設公司、高端網(wǎng)站制作、響應式網(wǎng)頁設計等建站業(yè)務,價格優(yōu)惠性價比高,為河北等各大城市提供網(wǎng)站開發(fā)制作服務。
其實log打印是由另一線程負責的,而且可能log也是多線程打印的,脊棚打櫻肢則出來前后不一致,是很有可能的。
要完成這個工作,需要完成三個部分的工作,以下依次說明:
一、建立服務器類
Java中有一個專門用來建立Socket服務器的類,名叫ServerSocket,可以用服務器需要使用的端口號作為參數(shù)來創(chuàng)建服務器對象。
ServerSocket server = new ServerSocket(9998)
這條語句創(chuàng)建了一個服務器對象,這個服務器使用9998號端口即在端口9998上注冊服務,這里稍微要注意的是端口的分配必須是唯一的。因為端口是為了唯一標識每臺計算機唯一服務的,另外端口號是從0~65535之間的,前1024個端口已經(jīng)被Tcp/Ip 作為保留端口,因此你所分配的端口只能是1024個之后的。當一個客戶端程序建立一個Socket連接,所連接的端口號為9998時,服務器對象server便響橋掘應這個連接,并且server.accept()方法會創(chuàng)建一個Socket對象。服務器端便閉消侍可以利用這個Socket對象與客戶進行通訊。
Socket incoming = server.accept() ; // 監(jiān)聽窗口,等待連接
進而得到輸入流和輸出流,并進行封裝
BufferedReader in = new BufferedReader(new
InputStreamReader(incoming.getInputStream()));
/*
當讀取文件時,先把內(nèi)容讀到緩存中,當調(diào)用in.readLine()時,再從緩存中以字符的方式讀取數(shù)據(jù)(以下簡稱“緩存字節(jié)讀取方式”)。
*/
PrintWriter ut = new PrintWriter(incoming.getOutputStream(),true);
隨后,就可以使用in.readLine()方法得到客戶端的輸入,也可以使用out.println()方法向客戶端發(fā)送數(shù)據(jù)。從而可以根據(jù)程序的需要對客戶端的不同請求進行回應。
在所有通訊結(jié)束以后應該關閉這兩個數(shù)據(jù)流,關閉的順序是先關閉輸出流,再關閉輸入流,即使用
out.close();
in.close();
二、建立客戶端代碼
相比服務器端,客戶端要簡單一些,客戶端只需用服務器所在機器的ip以及服務器的端口作為參數(shù)創(chuàng)建一個Socket對象。得到這個對象后,就可以用"建立服務器"部分介紹的方法實現(xiàn)數(shù)據(jù)的輸入和輸出。
Socket socket = new Socket("168.160.12.42",9998);
或:轎吵
Socket socket = new Socket(InetAddress.getLocalHost(),5678); // 向主機名為InetAddress.getLocalHost()的服務器申請連接
客戶機必須知道有關服務器的IP地址,對于著一點Java也提供了一個相關的類InetAddress 該對象的實例必須通過它的靜態(tài)方法來提供,它的靜態(tài)方法主要提供了得到本機IP 和通過名字或IP直接得到InetAddress的方法。
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(),true);
以上的程序代碼建立了一個Socket對象,這個對象連接到ip地址為168.160.12.42的主機上、端口為9998的服務器對象。并且建立了輸入流和輸出流,分別對應服務器的輸出和客戶端的寫入。
三、實例分析
服務方:
import java.io.*;
import java點虐 .*;
public class MyServer {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678); //在端口5678上注冊服務
Socket client=server.accept(); // 監(jiān)聽窗口,等待連接
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
BufferedReader serverInput=new BufferedReader(new InputStreamReader(System.in));
PrintWriter ut=new PrintWriter(client.getOutputStream());
while(true){
String str=in.readLine(); //// 讀取從client傳來的數(shù)據(jù)信息
str = serverInput.readLine(); // 讀取用戶鍵盤輸入的字符串
System.out.println(str); //服務器控制臺輸出數(shù)據(jù)信息
out.println("has receive...."); //服務器向客戶端發(fā)送信息:has receive....
out.flush();
if(str.equals("end"))
break;
}
client.close();
}
}
這個程序的主要目的在于服務器不斷接收客戶機所寫入的信息只到,客戶機發(fā)送"End"字符串就退出程序,并且服務器也會做出"Receive"為回應,告知客戶機已接收到消息。
客戶機代碼:
import java點虐 .*;
import java.io.*;
public class Client{
static Socket server;
public static void main(String[] args)throws Exception{
server=new Socket(InetAddress.getLocalHost(),5678); // 向主機名為InetAddress.getLocalHost()的服務器申請連接
BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream())); //客戶端建立輸入流并進行封裝
PrintWriter ut=new PrintWriter(server.getOutputStream());
BufferedReader wt=new BufferedReader(new InputStreamReader(System.in)); //客戶端從鍵盤輸入信息
while(true){
String str=wt.readLine(); //客戶端讀取(獲得)鍵盤的字符串
String str1=in.readLine(); // 從服務器獲得字符串
out.println(str); //客戶端向服務器發(fā)送信息
out.flush();
if(str.equals("end")){
break;
}
System.out.println(in.readLine());
}
server.close();
}
}
客戶機代碼則是接受客戶鍵盤輸入,并把該信息輸出,然后輸出"End"用來做退出標識。
這個程序只是簡單的兩臺計算機之間的通訊,如果是多個客戶同時訪問一個服務器呢?你可以試著再運行一個客戶端,結(jié)果是會拋出異常的。那么多個客戶端如何實現(xiàn)呢?
其實,簡單的分析一下,就可以看出客戶和服務通訊的主要通道就是Socket本身,而服務器通過accept方法就是同意和客戶建立通訊.這樣當客戶建立Socket的同時。服務器也會使用這一根連線來先后通訊,那么既然如此只要我們存在多條連線就可以了。那么我們的程序可以變?yōu)槿缦?
服務器:
import java.io.*;
import java點虐 .*;
public class MyServer {
public static void main(String[] args) throws IOException{
ServerSocket server=new ServerSocket(5678);
while(true){
Socket client=server.accept();
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter ut=new PrintWriter(client.getOutputStream());
while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive....");
out.flush();
if(str.equals("end"))
break;
}
client.close();
}
}
}
這里僅僅只是加了一個外層的While循環(huán),這個循環(huán)的目的就是當一個客戶進來就為它分配一個Socket直到這個客戶完成一次和服務器的交互,這里也就是接受到客戶的"End"消息.那么現(xiàn)在就實現(xiàn)了多客戶之間的交互了。但是.問題又來了,這樣做雖然解決了多客戶,可是是排隊執(zhí)行的。也就是說當一個客戶和服務器完成一次通訊之后下一個客戶才可以進來和服務器交互,無法做到同時服務,那么要如何才能同時達到既能相互之間交流又能同時交流呢?很顯然這是一個并行執(zhí)行的問題了。所以線程是最好的解決方案。
那么下面的問題是如何使用線程.首先要做的事情是創(chuàng)建線程并使得其可以和網(wǎng)絡連線取得聯(lián)系。然后由線程來執(zhí)行剛才的操作,要創(chuàng)建線程要么直接繼承Thread要么實現(xiàn)Runnable接口,要建立和Socket的聯(lián)系只要傳遞引用就可以了.而要執(zhí)行線程就必須重寫run方法,而run方法所做的事情就是剛才單線程版本main所做的事情,因此我們的程序變成了這樣:
import java點虐 .*;
import java.io.*;
public class MultiUser extends Thread{
private Socket client;
public MultiUser(Socket c){
this.client=c;
}
public void run(){
try{
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter ut=new PrintWriter(client.getOutputStream());
//Mutil User but can't parallel
while(true){
String str=in.readLine();
System.out.println(str);
out.println("has receive....");
out.flush();
if(str.equals("end"))
break;
}
client.close();
}catch(IOException ex){
}finally{
}
}
public static void main(String[] args)throws IOException{
ServerSocket server=new ServerSocket(5678);
while(true){
//transfer location change Single User or Multi User
MultiUser mu=new MultiUser(server.accept());
mu.start();
}
}
}
我的類直接從Thread類繼承了下來.并且通過構(gòu)造函數(shù)傳遞引用和客戶Socket建立了聯(lián)系,這樣每個線程就有了。一個通訊管道.同樣我們可以填寫run方法,把之前的操作交給線程來完成,這樣多客戶并行的Socket就建立起來了。
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Stack;
public class DoctorMain implements Runnable
{
private static DequeInteger binRenDeque;
private boolean onWork = false;
private boolean isDoctor = true;
public static Integer binRenNumber = 0;
public DoctorMain()
{
System.out.println("開始上班");
binRenDeque = new ArrayDequeInteger();
}
/**
* br/
* 方法概述 蠢或正br/
* 方法詳細概述 br/
* 版本 br/
* 作者 *
* @param args
*/團畝
public static void main(String[] args)
{
// TODO Auto-generated method stub
DoctorMain doctor=new DoctorMain();
doctor.setDoctor(true);
//帶悔上班了
doctor.setOnWork(true);
Thread th1=new Thread(doctor);
DoctorMain binRen=new DoctorMain();
binRen.setDoctor(false);
binRen.setOnWork(true);
Thread th2=new Thread(binRen);
th1.start();
th2.start();
try
{
Thread.sleep(60000);
doctor.setOnWork(false);
binRen.setOnWork(false);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run()
{
while (onWork)
{
try
{
//是醫(yī)生還是病人
if (isDoctor)
{
// 醫(yī)生給病人看病時間
Thread.sleep(2000);
if (!binRenDeque.isEmpty())
{
Integer number = binRenDeque.pollLast();
System.out.println("醫(yī)生正在給" + number + "號病人看病");
}
}
else
{
//病人來的間隔時間
Thread.sleep((int)(Math.random()*3000));
binRenNumber++;
System.out.println("來了一個病人,號碼是:"+binRenNumber);
binRenDeque.push(binRenNumber);
}
//列出所有等待的病人
for(Integer bn:binRenDeque)
{
System.out.println(bn+"號的病人在排隊");
}
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("醫(yī)生下班了");
}
public static DequeInteger getBinRenStack()
{
return binRenDeque;
}
public static void setBinRenStack(DequeInteger binRenStack)
{
DoctorMain.binRenDeque = binRenStack;
}
public boolean isOnWork()
{
return onWork;
}
public void setOnWork(boolean onWork)
{
this.onWork = onWork;
}
public boolean isDoctor()
{
return isDoctor;
}
public void setDoctor(boolean isDoctor)
{
this.isDoctor = isDoctor;
}
public static Integer getBinRenNumber()
{
return binRenNumber;
}
public static void setBinRenNumber(Integer binRenNumber)
{
DoctorMain.binRenNumber = binRenNumber;
}
}
分享題目:java排隊論代碼 java排序算法代碼實現(xiàn)
瀏覽路徑:http://chinadenli.net/article47/dsphsej.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設、網(wǎng)站改版、搜索引擎優(yōu)化、商城網(wǎng)站、軟件開發(fā)、服務器托管
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)