ネットワーク
物理ネットワークに基づき、接続の抽象化を確立するために、
+ R、入力cmdを勝ちます
コマンドを入力します。
IPCONFIG
pingが失敗した場合、ファイアウォールをオフにします
スタート---検索ファイアウォール
Socket 通信
ソケット - プラグ
ソケット - ネットワークソケット
IPアドレスによって、二つのホストは、それぞれ他のオブジェクトを見つけることができます
二つのホスト上で、各ポート番号を選択
ポートは排他的であり、0から1024がデフォルトのポートである--- HTTP、いくつかの共通サービス80 - HTTPS 443 - ftpの21 ...500万後、自動的にアサインするシステムで予約されたポートであります
私たちは、1024から50000の間のポート番号を選択するポートを選択しました
サーバー側
クライアントが開始接続を受動的に待ちます
ServerSocketをサーバー側では、ポート番号を選択し、指定されたポートで接続を開始するためにクライアントを待ちます
ServerSocketのssは= 新しい ServerSocketを(8000);
クライアントを待って、接続、接続チャネルとリターンチャネルサーバ側のプラグの接続オブジェクトを開始します
ソケットS = ss.accept()。
クライアント
サーバーに接続するためのイニシアチブをとります
ソケットS = 新しいソケット(IP、ポート)。
双方向の流れを削除します
入力ストリームにおける = s.getInputStream()。 OutputStream アウト = s.getOutputStream()。
タイムアウト
socket.setSoTimeout(ミリ秒)
データを受信するように設定、タイムアウトの長い待ち時間、タイムアウトがしてSocketTimeoutExceptionになります
例:
package demo; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class Server1 { public static void main(String[] args) throws Exception { ServerSocket ss = new ServerSocket(8000); System.out.println( "服务已经在 8000 端口上启动"); //暂停等待客户端发起连接 System.out.println("等待客户端连接"); Socket s = ss.accept(); System.out.println("客户端已连接"); //从插头对象,获取输入流和输出流 InputStream in = s.getInputStream(); OutputStream out = s.getOutputStream(); /* * 通信协议,通信流程,数据格式 * * 服务器端: * 1. 接收 "hello" * 2. 发送 "world" */ for (int i = 0; i < 5; i++) { char c = (char) in.read(); System.out.print(c); } out.write("world".getBytes()); out.flush(); //刷出内存缓存 s.close();//断开连接 ss.close();//停止服务,释放端口 } }
Client
package demo; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class Client1 { public static void main(String[] args) throws Exception { Socket s = new Socket("旁边同学ip", 8000); InputStream in = s.getInputStream(); OutputStream out = s.getOutputStream(); /* 客户端: * 1. 发送 "hello" * 2. 接收 "world" */ out.write("hello".getBytes()); out.flush(); //刷出内存缓存 for (int i = 0; i < 5; i++) { char c = (char) in.read(); System.out.print(c); } s.close(); } }
阻塞操作
ss.accept()
暂停,等待客户端发起连接
in.read()
对方不发送数据,暂停,死等数据
服务器端的线程模型
回声
客户端发送到服务器的数据,原封不动的发回客户端
EchoServer
package demo; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class EchoServer { public void launch() { new Thread() { @Override public void run() { try { ServerSocket ss = new ServerSocket(8000); System.out.println("服务已在 8000 端口上启动"); while(true) { System.out.println("等待下一个客户端连接"); Socket s = ss.accept(); System.out.println("客户端已连接"); TongXinThread t = new TongXinThread(s); t.start(); } } catch (Exception e) { System.out.println( "无法在 8000 端口上启动服务,或服务已停止"); } } }.start(); } class TongXinThread extends Thread { Socket s; public TongXinThread(Socket s) { this.s = s; } @Override public void run() { /* * 通信协议,流程和格式 * UTF-8编码的字符串, * 每段字符串末尾添加换行 * * BR--ISR--网络输入流 * PW--OSW--网络输出流 */ try { BufferedReader in = new BufferedReader( new InputStreamReader( s.getInputStream(), "UTF-8")); PrintWriter out = new PrintWriter( new OutputStreamWriter( s.getOutputStream(),"UTF-8")); String line; while((line = in.readLine()) != null) { out.println(line); out.flush(); } //断开 } catch (Exception e) { //断开 } System.out.println("一个客户端端已断开"); } } public static void main(String[] args) { EchoServer s = new EchoServer(); s.launch(); } }
EchoClient
package demo; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.net.Socket; import java.util.Scanner; public class EchoClient { public static void main(String[] args) throws Exception { Socket s = new Socket("找一个人启动服务器", 8000); BufferedReader in = new BufferedReader( new InputStreamReader( s.getInputStream(), "UTF-8")); PrintWriter out = new PrintWriter( new OutputStreamWriter( s.getOutputStream(),"UTF-8")); while(true) { System.out.print("输入:"); String str = new Scanner(System.in).nextLine(); out.println(str); out.flush(); String echo = in.readLine(); System.out.println("回声:"+echo); System.out.println("-----------------"); } } }
ChatServer
package demo; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; public class ChatServer { private ArrayList<TongXinThread> list = new ArrayList<>(); public void launch() { //启动服务线程 new Thread() { @Override public void run() { try { ServerSocket ss = new ServerSocket(8000); System.out.println("聊天室服务器已启动"); while(true) { Socket s = ss.accept(); TongXinThread t = new TongXinThread(s); t.start(); } } catch (Exception e) { System.out.println( "服务无法在 8000 端口上启动,或服务已经停止"); } } }.start(); } class TongXinThread extends Thread { Socket s; BufferedReader in; PrintWriter out; private String name; public TongXinThread(Socket s) { this.s = s; } public void send(String msg) { out.println(msg); out.flush(); } public void sendAll(String msg) { synchronized (list) { for (TongXinThread t : list) { t.send(msg); } } } @Override public void run() { try { //UTF-8, 换行 in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8")); out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),"UTF-8")); //接收客户端的昵称 this.name = in.readLine(); //把当前通信线程实例,加入集合 synchronized (list) { list.add(this); } //发送欢迎信息 send("欢迎进入激情聊天室"); //群发上线消息 sendAll(name+"进入了聊天室,在线人数:"+list.size()); String line; while((line = in.readLine()) != null) { sendAll(name+"说:"+line); } //断开 } catch (Exception e) { //断开 } //删除当前通信线程实例 synchronized (list) { list.remove(this); } //群发离线消息 sendAll(name+"离开了聊天室,在线人数:"+list.size()); } } public static void main(String[] args) { ChatServer s = new ChatServer(); s.launch(); } }
ChatClient
package demo; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.net.Socket; import java.util.LinkedList; import java.util.Scanner; public class ChatClient { private Socket s; private BufferedReader in; private PrintWriter out; private String name; private LinkedList<String> list = new LinkedList<>(); private boolean flag; //开关 public void launch() { try { s = new Socket("192.168.21.61", 8000); in = new BufferedReader(new InputStreamReader(s.getInputStream(), "UTF-8")); out = new PrintWriter(new OutputStreamWriter(s.getOutputStream(),"UTF-8")); //昵称 System.out.print("起一个昵称: "); name = new Scanner(System.in).nextLine(); out.println(name); out.flush(); //接收线程 new Thread() { @Override public void run() { receive(); } }.start(); //输入线程 new Thread() { @Override public void run() { input(); } }.start(); //打印线程 new Thread() { @Override public void run() { print(); } }.start(); } catch (Exception e) { System.out.println("无法连接聊天室服务器"); e.printStackTrace(); } } protected void print() { while(true) { synchronized (list) { while (list.isEmpty() || flag) { try { list.wait(); } catch (InterruptedException e) { } } String msg = list.removeFirst(); System.out.println(msg); } } } protected void input() { System.out.println("按回车输入聊天内容"); while(true) { new Scanner(System.in).nextLine(); flag = true;//打开开关 System.out.print("输入聊天内容:"); String s = new Scanner(System.in).nextLine(); out.println(s); out.flush(); flag = false;//关闭开关 //通知打印线程可以继续打印 synchronized (list) { list.notify(); } } } protected void receive() { try { String line; while((line = in.readLine()) != null) { synchronized (list) { list.add(line); //通知打印线程已经有数据可以打印了 list.notify(); } } } catch (Exception e) { } System.out.println("已经与服务器断开连接"); } public static void main(String[] args) { ChatClient c = new ChatClient(); c.launch(); } }