每當程序建立一個新的套接字連接,也就是說當成功調用accept的時候,將創建一個新的線程來處理服務器和該客戶端之間的連接,而主程序將立即返回并等待下一個連接。
package test;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PRintWriter;import java.net.ServerSocket;import java.net.Socket;public class Server { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(8189); int i=5656; while(true){ Socket s = ss.accept(); SocketThread socketThread = new SocketThread(s,++i); new Thread(socketThread).start(); } }}class SocketThread implements Runnable{ private Socket s; private int i; public SocketThread(Socket s,int i) { this.s=s; this.i=i; } public void run(){ try { InputStream is = s.getInputStream(); OutputStream os = s.getOutputStream(); PrintWriter pw = new PrintWriter(os); BufferedReader bf = new BufferedReader(new InputStreamReader(is)); pw.println("hello,"+i+",enter bye to close"); pw.flush(); boolean flag=true; String input; while((input=bf.readLine())!=null&& flag){ pw.println(i+"==>"+input); if(input.equals("bye")){ flag=false; } pw.flush(); } } catch (IOException e) { e.printStackTrace(); }finally{ try { s.close(); } catch (IOException e) { e.printStackTrace(); } } }}使用上面的服務器就可以使多個客戶端連接。
window多個cmd中使用telnet 127.0.0.1 8189,就可以創建多個客戶端。
telnet在控制面板中“程序和功能”“打開或關閉windows功能”里面,要勾選才有用。
下面的程序也行
Socket a = new Socket("127.0.0.1",8189); InputStream is = a.getInputStream(); OutputStream os = a.getOutputStream(); PrintWriter pw = new PrintWriter(os); BufferedReader bf = new BufferedReader(new InputStreamReader(is)); Scanner scanner = new Scanner(System.in); String s; while((s=bf.readLine())!=null){ System.out.println(s); pw.println(scanner.nextLine()); pw.flush(); }多個類一起運行也可以看出效果。半關閉
半關閉( half-close)提供了這樣一種能力:套接字連接的一端可以終止其輸出,同時仍舊可以接收來自另一端的數據。可以通過關閉一個套接字的輸出流來表示發送給服務器的請求數據已經結束,但是必須保持輸入流處于打開狀態。
當然,該協議只適用于一站式( one-shot)的服務,例如HTTP服務,在這種服務中,客戶端連接服務器,發送一個請求,捕獲響應信息,然后斷開連接。
void shutdownOutput() 將輸出流設為“流結束”。void shutdownInput() 將輸入流設為“流結束”。boolean isOutputShutdown() 如果輸出已被關閉,則返回true。boolean isInputShutdown() 如果輸入已被關閉,則返回true。其實就是輸入流或者輸出流中一個已經用完了,不會用了就把它關閉了,但是另一個流還有用,不關閉。可中斷的套接字
當連接到一個套接字時,當前線程將會被阻塞直到建立連接或產生超時為止。同樣地,當通過套接字讀寫數據時,當前線程也會被阻塞直到操作成功或產生超時為止。
在交互式的應用中,也許會考慮為用戶提供一個功能,用以取消那些看似不會成功的連接。但是,當線程因套接字長時間無法響應而發生阻塞時,
無法通過調用interrupt來解除阻塞。
為了中斷套接字操作,可以使用java.nio包提供的一個特性—SocketChannel類。
SocketChannel sc =SocketChannel.open(new InetSocketAddress(hostname, port));通道( channel)并沒有與之相關聯的流。實際上,它所擁有的read和write方法都是通過調用Buffer對象來實現的。 ReadableByteChannel接口和WritableByteChannel接口都聲明了這兩個方法。SocketChannel sc =SocketChannel.open(new InetSocketAddress("127.0.0.1", 8189)); Scanner scanner = new Scanner(sc); InputStream in = Channels.newInputStream(sc); OutputStream put = Channels.newOutputStream(sc);假設線程正在執行打開、讀取或寫入操作,此時如果線程發生中斷,那么這些操作將不會陷入阻塞,而是以拋出異常的方式結束。InetSocketAddress(String hostname, int port)通過主機和端口參數創建一個地址對象,并在創建過程中解析主機名。如果主機名不能被解析,那么該地址對象的unresolved屬性將被設為true。boolean isUnresolved()如果不能解析該地址對象,則返回true。
新聞熱點
疑難解答