public class Message {
創(chuàng)新互聯(lián)建站主要從事網(wǎng)站制作、成都網(wǎng)站設計、網(wǎng)頁設計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務。立足成都服務東阿,10年網(wǎng)站建設經(jīng)驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:18980820575
public static void main(String[] args){
String name;
int age;
System.out.println("請輸入姓名,回車結束:"); //提示輸入
Scanner sc = new Scanner(System.in);
name = sc.nextLine(); //為變量賦值
System.out.println("請輸入年齡,回車結束:");
age = sc.nextInt();
System.out.println("姓名:"+name+"\n年齡:"+age); //打印姓名及年齡
}
}
//不知道這樣行么?
15.3 服務多個客戶
JabberServer可以正常工作,但每次只能為一個客戶程序提供服務。在典型的服務器中,我們希望同時能處理多個客戶的請求。解決這個問題的關鍵就是多線程處理機制。而對于那些本身不支持多線程的語言,達到這個要求無疑是異常困難的。通過第14章的學習,大家已經(jīng)知道Java已對多線程的處理進行了盡可能的簡化。由于Java的線程處理方式非常直接,所以讓服務器控制多名客戶并不是件難事。
最基本的方法是在服務器(程序)里創(chuàng)建單個ServerSocket,并調(diào)用accept()來等候一個新連接。一旦accept()返回,我們就取得結果獲得的Socket,并用它新建一個線程,令其只為那個特定的客戶服務。然后再調(diào)用accept(),等候下一次新的連接請求。
對于下面這段服務器代碼,大家可發(fā)現(xiàn)它與JabberServer.java例子非常相似,只是為一個特定的客戶提供服務的所有操作都已移入一個獨立的線程類中:
//: MultiJabberServer.java
// A server that uses multithreading to handle
// any number of clients.
import java.io.*;
import java點虐 .*;
class ServeOneJabber extends Thread {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public ServeOneJabber(Socket s)
throws IOException {
socket = s;
in =
new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
// Enable auto-flush:
out =
new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())), true);
// If any of the above calls throw an
// exception, the caller is responsible for
// closing the socket. Otherwise the thread
// will close it.
start(); // Calls run()
}
public void run() {
try {
while (true) {
String str = in.readLine();
if (str.equals("END")) break;
System.out.println("Echoing: " + str);
out.println(str);
}
System.out.println("closing...");
} catch (IOException e) {
} finally {
try {
socket.close();
} catch(IOException e) {}
}
}
}
public class MultiJabberServer {
static final int PORT = 8080;
public static void main(String[] args)
throws IOException {
ServerSocket s = new ServerSocket(PORT);
System.out.println("Server Started");
try {
while(true) {
// Blocks until a connection occurs:
Socket socket = s.accept();
try {
new ServeOneJabber(socket);
} catch(IOException e) {
// If it fails, close the socket,
// otherwise the thread will close it:
socket.close();
}
}
} finally {
s.close();
}
}
} ///:~
每次有新客戶請求建立一個連接時,ServeOneJabber線程都會取得由accept()在main()中生成的Socket對象。然后和往常一樣,它創(chuàng)建一個BufferedReader,并用Socket自動刷新PrintWriter對象。最后,它調(diào)用Thread的特殊方法start(),令其進行線程的初始化,然后調(diào)用run()。這里采取的操作與前例是一樣的:從套掃字讀入某些東西,然后把它原樣反饋回去,直到遇到一個特殊的"END"結束標志為止。
同樣地,套接字的清除必須進行謹慎的設計。就目前這種情況來說,套接字是在ServeOneJabber外部創(chuàng)建的,所以清除工作可以“共享”。若ServeOneJabber構建器失敗,那么只需向調(diào)用者“擲”出一個違例即可,然后由調(diào)用者負責線程的清除。但假如構建器成功,那么必須由ServeOneJabber對象負責線程的清除,這是在它的run()里進行的。
請注意MultiJabberServer有多么簡單。和以前一樣,我們創(chuàng)建一個ServerSocket,并調(diào)用accept()允許一個新連接的建立。但這一次,accept()的返回值(一個套接字)將傳遞給用于ServeOneJabber的構建器,由它創(chuàng)建一個新線程,并對那個連接進行控制。連接中斷后,線程便可簡單地消失。
如果ServerSocket創(chuàng)建失敗,則再一次通過main()擲出違例。如果成功,則位于外層的try-finally代碼塊可以擔保正確的清除。位于內(nèi)層的try-catch塊只負責防范ServeOneJabber構建器的失??;若構建器成功,則ServeOneJabber線程會將對應的套接字關掉。
為了證實服務器代碼確實能為多名客戶提供服務,下面這個程序?qū)?chuàng)建許多客戶(使用線程),并同相同的服務器建立連接。每個線程的“存在時間”都是有限的。一旦到期,就留出空間以便創(chuàng)建一個新線程。允許創(chuàng)建的線程的最大數(shù)量是由final int maxthreads決定的。大家會注意到這個值非常關鍵,因為假如把它設得很大,線程便有可能耗盡資源,并產(chǎn)生不可預知的程序錯誤。
//: MultiJabberClient.java
// Client that tests the MultiJabberServer
// by starting up multiple clients.
import java點虐 .*;
import java.io.*;
class JabberClientThread extends Thread {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private static int counter = 0;
private int id = counter++;
private static int threadcount = 0;
public static int threadCount() {
return threadcount;
}
public JabberClientThread(InetAddress addr) {
System.out.println("Making client " + id);
threadcount++;
try {
socket =
new Socket(addr, MultiJabberServer.PORT);
} catch(IOException e) {
// If the creation of the socket fails,
// nothing needs to be cleaned up.
}
try {
in =
new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
// Enable auto-flush:
out =
new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())), true);
start();
} catch(IOException e) {
// The socket should be closed on any
// failures other than the socket
// constructor:
try {
socket.close();
} catch(IOException e2) {}
}
// Otherwise the socket will be closed by
// the run() method of the thread.
}
public void run() {
try {
for(int i = 0; i 25; i++) {
out.println("Client " + id + ": " + i);
String str = in.readLine();
System.out.println(str);
}
out.println("END");
} catch(IOException e) {
} finally {
// Always close it:
try {
socket.close();
} catch(IOException e) {}
threadcount--; // Ending this thread
}
}
}
public class MultiJabberClient {
static final int MAX_THREADS = 40;
public static void main(String[] args)
throws IOException, InterruptedException {
InetAddress addr =
InetAddress.getByName(null);
while(true) {
if(JabberClientThread.threadCount()
MAX_THREADS)
new JabberClientThread(addr);
Thread.currentThread().sleep(100);
}
}
} ///:~
JabberClientThread構建器獲取一個InetAddress,并用它打開一個套接字。大家可能已看出了這樣的一個套路:Socket肯定用于創(chuàng)建某種Reader以及/或者Writer(或者InputStream和/或OutputStream)對象,這是運用Socket的唯一方式(當然,我們可考慮編寫一、兩個類,令其自動完成這些操作,避免大量重復的代碼編寫工作)。同樣地,start()執(zhí)行線程的初始化,并調(diào)用run()。在這里,消息發(fā)送給服務器,而來自服務器的信息則在屏幕上回顯出來。然而,線程的“存在時間”是有限的,最終都會結束。注意在套接字創(chuàng)建好以后,但在構建器完成之前,假若構建器失敗,套接字會被清除。否則,為套接字調(diào)用close()的責任便落到了run()方法的頭上。
threadcount跟蹤計算目前存在的JabberClientThread對象的數(shù)量。它將作為構建器的一部分增值,并在run()退出時減值(run()退出意味著線程中止)。在MultiJabberClient.main()中,大家可以看到線程的數(shù)量會得到檢查。若數(shù)量太多,則多余的暫時不創(chuàng)建。方法隨后進入“休眠”狀態(tài)。這樣一來,一旦部分線程最后被中止,多作的那些線程就可以創(chuàng)建了。大家可試驗一下逐漸增大MAX_THREADS,看看對于你使用的系統(tǒng)來說,建立多少線程(連接)才會使您的系統(tǒng)資源降低到危險程度。
最簡單的java代碼肯定就是這個了,如下:
public class MyFirstApp
{
public static void main(String[] args)
{
System.out.print("Hello world");
}
}
“hello world”就是應該是所有學java的新手看的第一個代碼了。如果是零基礎的新手朋友們可以來我們的java實驗班試聽,有免費的試聽課程幫助學習java必備基礎知識,有助教老師為零基礎的人提供個人學習方案,學習完成后有考評團進行專業(yè)測試,幫助測評學員是否適合繼續(xù)學習java,15天內(nèi)免費幫助來報名體驗實驗班的新手快速入門java,更好的學習java!
package?socket;
import?java.io.BufferedReader;
import?java.io.IOException;
import?java.io.InputStreamReader;
import?java.io.PrintWriter;
import?java點虐 .ServerSocket;
import?java點虐 .Socket;
public?class?SocketService?{
//搭建服務器端
public?static?void?main(String[]?args)?throws?IOException{
SocketService?socketService?=?new?SocketService();
//1、a)創(chuàng)建一個服務器端Socket,即SocketService?
socketService.oneServer();
}
public??void?oneServer(){
try{
ServerSocket?server=null;
try{
server=new?ServerSocket(5209);
//b)指定綁定的端口,并監(jiān)聽此端口。
System.out.println("服務器啟動成功");
//創(chuàng)建一個ServerSocket在端口5209監(jiān)聽客戶請求
}catch(Exception?e)?{
System.out.println("沒有啟動監(jiān)聽:"+e);
//出錯,打印出錯信息
}
Socket?socket=null;
try{
socket=server.accept();
//2、調(diào)用accept()方法開始監(jiān)聽,等待客戶端的連接?
//使用accept()阻塞等待客戶請求,有客戶
//請求到來則產(chǎn)生一個Socket對象,并繼續(xù)執(zhí)行
}catch(Exception?e)?{
System.out.println("Error."+e);
//出錯,打印出錯信息
}
//3、獲取輸入流,并讀取客戶端信息?
String?line;
BufferedReader?in=new?BufferedReader(new?InputStreamReader(socket.getInputStream()));
//由Socket對象得到輸入流,并構造相應的BufferedReader對象
PrintWriter?writer=new?PrintWriter(socket.getOutputStream());
//由Socket對象得到輸出流,并構造PrintWriter對象
BufferedReader?br=new?BufferedReader(new?InputStreamReader(System.in));
//由系統(tǒng)標準輸入設備構造BufferedReader對象
System.out.println("Client:"+in.readLine());
//在標準輸出上打印從客戶端讀入的字符串
line=br.readLine();
//從標準輸入讀入一字符串
//4、獲取輸出流,響應客戶端的請求?
while(!line.equals("end")){
//如果該字符串為?"bye",則停止循環(huán)
writer.println(line);
//向客戶端輸出該字符串
writer.flush();
//刷新輸出流,使Client馬上收到該字符串
System.out.println("Server:"+line);
//在系統(tǒng)標準輸出上打印讀入的字符串
System.out.println("Client:"+in.readLine());
//從Client讀入一字符串,并打印到標準輸出上
line=br.readLine();
//從系統(tǒng)標準輸入讀入一字符串
}?//繼續(xù)循環(huán)
//5、關閉資源?
writer.close();?//關閉Socket輸出流
in.close();?//關閉Socket輸入流
socket.close();?//關閉Socket
server.close();?//關閉ServerSocket
}catch(Exception?e)?{//出錯,打印出錯信息
System.out.println("Error."+e);
}
}
}
分享文章:java服務端簡單代碼 java編寫服務器和客戶端
瀏覽地址:http://www.rwnh.cn/article36/ddcpipg.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供手機網(wǎng)站建設、Google、品牌網(wǎng)站制作、App開發(fā)、建站公司、關鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)