JavaSE:TCP相关的ServerSocket类 和 Socket类

0.  一个关于C/S架构的比喻 (客户给汽车充电)java

 

 对照:一个关于TCP协议的比喻 (客户给汽车充电)服务器

 

 

 

1.  ServerSocket 类网络

    <1>  java.net.ServerSocket类:用于描述服务器套接字信息(大插排)架构

        所谓套接字(Socket),就是对网络中不一样主机上的应用进程之间进行双向通讯的端点的抽象  socket

    <2>  经常使用的方法以下:ide

方法声明 功能介绍
ServerSocket(int port) 根据参数指定的端口号,来构造对象
Socket accept() 侦听,并接收,到此套接字的链接请求
void close() 用于关闭套接字

 

2.  Socket类this

    <1>  java.net.Socket类:用于描述客户端套接字,是两台机器间通讯的端点(小插排)。spa

    <2>  常见的方法以下:.net

方法声明 功能介绍
Socket(String host,int port) 根据指定主机名 和 端口来构造对象
InputStream getInputStream() 获取当前套接字的输入流
OutputStream getOutputStream() 获取当前套接字的输出流
void close() 用于关闭套接字

    <3>  注意事项线程

          1.  客户端Socket 与 服务器端 Socket对应,都包含输入 和 输出流

          2.  客户端的socket.getInputStrream() 链接于服务器 socket.getOutputStream()

          3.  客户端的socket.getOutputStream()链接于服务器socket.getInputStream()

 

3. 代码示例

    <1>   搭建服务器

 1 class ServerStringTest {
 2 
 3     main(){
 4         ServerSocket ss = null;
 5         Socket s = null;
 6 
 7         try{
 8             //    1.建立ServerSocket类型的对象,并提供端口号
 9             ss = new ServerSocket(8888);
10 
11             //    2.等待客户端的链接请求,调用accept方法
12             while(true){
13                 println("等待客户端的链接请求...");
14                 //    当没有客户端链接时,则,服务器阻塞在accept方法的调用处
15                 s = ss.accept();
16                 println("客户端" + s.getInetAddress() + "链接成功!");
17 
18                 //    3.每当有一个客户端链接成功,则须要启动一个线程,为之服务
19                 new ServerThread(s).start(); // 见<2> 20             } 
21         } catch (IOException e){
22             e.printStackTrace();
23         } finally {
24                 //    4.关闭Socket,并释放有关的资源
25                 if(null != ss){
26                     try{
27                         ss.close();
28                     }catch(IOException e){
29                         e.printStackTrace();
30                     }
31                 }
32         }
33 
34     }
35 }

    <2>  为客户端进行服务的线程

 1 class ServerThread extends Thread {
 2 
 3     private Socket s;
 4 
 5     public ServerThread(Socket s){
 6         this.s = s;
 7     }
 8 
 9     @Override
10     public void run(){
11         BufferedReader br = null;
12         PrintStream ps = null;
13 
14         try{
15             //    使用输入输出流进行通讯
16             br = new BufferedReader (new InputStreamReader(s.getInputStream()) );
17             ps = new PrintStream(s.getOutputStream() );
18 
19             while(true){
20                 //    对客户端发来字符串内容的接收,并打印
21                 //    当没有数据发来时,下面的方法会造成阻塞
22                 String s1 = br.readLine();
23                 InetAddress inetAddress = s.getInetAddress();
24                 println("客户端" + inetAddress + "发来的字符串内容是:" + s1);
25                 //    当客户端发来的内容为"bye"时,则聊天结束
26                 if("bye".equalsIgnoreCase(s1)){
27                     println("客户端" + inetAddress + "已下线!");
28                 }
29 
30                 // 服务器向客户端回发字符串内容 "I received!"
31                 ps.println("I received!");
32                 println("服务器发送数据成功!")
33             }
34         } catch (IOException e){
35             e.printStackTrace();
36         } finally {
37             if (null != ps){
38                 ps.close();
39             }
40             if (null != br) {
41                 try {
42                     br.close();
43                 } catch (IOException e) {
44                     e.printStackTrace();
45                 }
46             }
47             if (null != s) {
48                 try {
49                     s.close();
50                 } catch (IOException e) {
51                     e.printStackTrace();
52                 }
53             }
54         }
55     }
56 }

    <3>  客户端

 

    

 1 class ClientStringTest {
 2     main(){
 3         Socket s = null;
 4         PrinterStream ps = null;
 5         Scanner sc = null;
 6         BufferedReader br = null;
 7 
 8         try{
 9             //    1.    建立Socket类型的对象,并提供服务器的主机名和端口号
10             s = new Socket("127.0.0.1",8888);
11             println("链接服务器成功!");
12 
13             //    2.    使用输入输出流,进行通讯
14             sc = new Scanner(System.in);
15             ps = new PrinterStream(s.getOutputStream());
16             br = new BufferedReader(new InputStreamReader(s.getInputStream()));
17 
18             while(true){
19                 //    Thread.sleep(10000);
20                 //    实现客户端发送的内容,由用户从键盘输入
21                 println("请输入要发送的数据内容:");
22                 String str1 = sc.next();
23 
24                 //    实现客户端向服务器发送字符串内容"hello"
25                 //    ps.println("hello");
26                 ps.println(str1);
27                 println("客户端发送数据内容成功!");
28 
29                 //    当发送的数据内容为"bye"时,则聊天结束
30                 if ("bye".equalsIgnoreCase(str1) ){
31                     println("聊天结束!");
32                     break;
33                 }
34 
35                 //    实现接收服务器发来的字符串内容,并打印
36                 String str2 = br.readLine();
37                 println("服务器回发的消息是:" + str2);
38             }
39         } catch (IOException /*| InterruptedException*/ e) {
40             e.printStackTrace();
41         } finally {
42             // 3.关闭Socket并释放有关的资源
43             if (null != br) {
44                 try {
45                     br.close();
46                 } catch (IOException e) {
47                     e.printStackTrace();
48                 }
49             }
50             if (null != ps) {
51                 ps.close();
52             }
53             if (null != sc) {
54                 sc.close();
55             }
56             if (null != s) {
57                 try {
58                     s.close();
59                 } catch (IOException e) {
60                     e.printStackTrace();
61                 }
62             }
63         }
64     }
65 }