博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java知多少(105)套接字(Socket)
阅读量:6253 次
发布时间:2019-06-22

本文共 8540 字,大约阅读时间需要 28 分钟。

网络应用模式主要有:

  • 主机/终端模式:集中计算,集中管理;
  • 客户机/服务器(Client/Server,简称C/S)模式:分布计算,分布管理;
  • 浏览器/服务器模式:利用Internet跨平台。

www(万维网)就是建立在客户机/服务器模式上,以HTML语言和HTTP协议为基础,能够提供各种Internet服务的信息浏览系统。网络信息放在主机的不同位置,www服务器利用超文本链路链接各项信息。www客户机(浏览器Brower)负责与服务器建立联系,向服务器发送请求,处理HTML超媒体,提供图形用户界面(GUI),显示信息等。
在客户机/服务器工作模式中,在Server端,要准备接受多个Client端计算机的通信。为此,除用IP地址标识Internet上的计算机之外,另还引入端口号,用端口号标识正在Server端后台服务的线程。端口号与IP地址的组合称为网络套接字(socket)。
Java语言在实现C/S模式中,套接字分为两类:

  • 在Server端,ServerSocket类支持底层的网络通信;
  • 在Client端,Socket类支持网络的底层通信。

Server机通过端口(总线I/O地址)提供面向Client机的服务;Server机在它的几个不同端口分别同时提供几种不同的服务。Client接入Server的某一端口,通过这个端口提请Server机为其服务。规定:端口号0~1023供系统专用。例如,HTTP协议在端口80,telnet协议在端口23。端口1024~65535供应用程序使用。

当Client程序和Server程序需要通信时,可以用Socket类建立套接字连接。套接字连接可想象为一个电话呼叫:最初是Client程序建立呼叫,Server程序监听;呼叫完成后,任何一方都可以随时讲话。
双方实现通信有流式socket和数据报式socket两种可选方式:

  • 流式socket是有连接的通信,即TCP(Transmission Control Protocol):每次通信前建立连接,通信结束后断开连接。特点是可以保证传输的正确性、可靠性。
  • 数据报式socket是无连接的通信,即UDP(User Datagram Protocol):将欲传输的数据分成 小包,直接上网发送。无需建立连接和拆除连接,速度快,但无可靠保证。

流式socket在Client程序和Server程序间建立通信的通道。每个socket可以进行读和写两种操作。对于任一端,与对方的通信会话过程是:
建立socket连接,获得输入/输出流,读数据/写数据,通信完成后关闭socket(拆除连接)。流式Socket的通信过程见【例 13-1】。
利用socket的构造方法,可以在客户端建立到服务器的套接字对象:
    Socket(String host,int port):host是服务器的IP地址,port是端口号,这些是预先约定的。
例如,代码:

1     try{2         Socket mySocket = new Socket(“http://www.weixueyuan.net” ,1860);3     }catch(IOException e){}

然后,用getInputStream()方法获得输入流,用这个输入流读取服务器放入“线路”的信息;用getOutputStream()方法获得输出流,用这个输出流将信息写入“线路”。

利用ServerSocket的构造方法可以在服务器建立接受客户套接字的服务器套接字对象:

ServerSocket(int port):指定端口号,创建一个ServerSocket对象。端口号port要与客户呼叫的端口号相同。为此,用以下形式代码:    try{        ServerSocket serverSocket = new ServerSocket(1860);    }catch(IOException e){}

服务器端程序在指定的端口监听,当收到Client程序发出的服务请求时,创建一个套接字对象与该端口对应的Client程序通信。例如,执行上述建立服务器套接字对象的代码,确立了对象serverSocket后,就可能它使用accept()方法,得到Socket对象,接收Client程序来自套接字mySocket的信息。如以下代码所示:

try{        Socket sc = serverSocket.accept();//ac是一个Socket对象    }catch(IOException e){}要撤销服务,可以关闭Socket对象sc:    sc.close();

【例 13-3】C/S模式中的Client端应用程序。这是一个Client端的流式Socket通信的简单实例,代码说明Client端程序的编写方法。例中,Client程序向服务器主机的端口4441提出请求,连接建立后完成对服务器的读写

1 import java.io.*; 2 import java.net.*; 3 public class Client{ 4     public static void main(String args[]){ 5         String s = null;Socket mySocket; 6         DataInputStream in = null;DataOutputStream out = null; 7         try{ 8             mySocket = new Socket(“localhost”,4441); 9             in = new DataInputStream(mySocket.getInputStream());10             out = new DataOutputStream(mySocket.getOutputStream());11             out.writeUTF(“good server!”);12             while(true){13                 s = in.readUTF();14                 if(s==null) break;15                 else System.out.println(s);16             }17             mySocket.close();18         }catch(IOException e){19             System.out.println(“can’t connect”);20         }21     }22 }

【例 13-4】与例10.3 Client端应用程序对应的Server端应用程序。程序在4441端口监听,当检测到有客户机请求时,产生一个内为“客户,你好,我是服务器”的字符串输出到客户端

1 import java.io.*;import java.net.*; 2 public class Server{ 3     public static void main(String args[]){ 4         ServerSocket server = null; 5         Socket you = null;String s = null; 6         DataOutputStream out = null; 7         DataInputStream in = null; 8         try{ 9             server = new ServerSocket(4441);10         }catch(IOException e1){11             system.out.println(“ERROR:” +e1);12         }13         try{14             you = server.accept();15             in = new DataInputStream(you.getInputStream());16             out = new DataOutputStream(you. getOutputStream());17             while(true){18                 s = in.readUTF();19                 if(s!=null) break;20             }21             out.writeUTF(“客户,你好,我是服务器”);22             out.close();23         }24         catch(IOException e){System.out.println(“ERROR:”+e);}25     }26 }

为了充分发挥计算机的平行工作能力,可以把套接字连接工作让一个线程完成。当客户端要请求服务器给予服务,或当服务器端接收到一个客户的服务请求,就启动一个专门完成信息通信的线程,在该线程中创建输入输出流,并完成客户端与服务器端的信息交流。

【例 13-5】 将套接字连接工作置于线程的客户端小应用程序。界面在有一个发送信息按纽、一个文本框和一个文本区。客户端应用程序首先与服务器建立套接字连接。使用数据输入流in反复读取服务器放入线路里的信息,将收到的信息在文本区中显示。婐志取的信息是“结束”,则关闭套接字连接,并结束程序。用户也可在文本框输入信息,并按发送信息按钮,则客户端程序利用数据输出流out,将文本框中的内容发送给服务器。

1 import java.net.*; 2 import java.io.*; 3 import java.awt.*; 4 import javax.swing.*; 5 import java.awt.event.*; 6 import java.applet.*; 7 public class Aclient extends Applet implements Runnable,ActionListener{ 8     JButton button; JTextField textF; JTextArea textA; 9     Socket socket; Thread thread;10     DataInputStream in; DataOutputStream out;11     public void init(){12         setBackground(new Color(120,153,137));13         setLayout(new BorderLayout());14         Button = new JButton(“发送信息”);15         textF = new JTextField(20);16         textA = new JTextArea(20,30);17         setSize(450,350);18         JPanel p = new JPanel();19         p.add(textF); p.add(button);20         add(textA,”Center”); add(p,”South”);21         button.addActionListener(this);22     }23     public void start(){24         try{25             socket = new Socket(this.getCodeBase().getHost(),4441);26             in = new DataInputStream(socket.getInputStream());27             out = new DataOutputStream(socket.getOutputStream());28         }catch(IOException e){}29         if(thread==null){30             thread = new Thread(this);31             thread.setPriority(Thread.MIN_PRIORITY);32             thread.start();33         }34     }35     public void run(){36         String s = null;37         while(true){38             try{39                 s = in.readUTF();40             }catch(IOException e){}41             if(s.equals(“结束”)){42                 try{43                     socket.close();break;44                 }catch(IOException e){}45             }else texA.append(s + “\n”);46         }47     }48     public void actionPerformed(ActionEvent e){49         if(e.getSource()==button){50             String s = textF.getText();51             if(s! = null){52                 try{53                     out.writeUTF(s);54                 }catch(IOException e1){}55             }56             else{57                 try{58                     out.writeUTF(“请说话”);59                 }60                 catch(IOException e1){}61             }62         }63     }64 }

【例 13-6】对应例10.5客户端小应用程序的服务器端小应用程序。程序以端4441建立与客户端的套接字连接,服务器端收到客户端的申请后,以客户的套接字建立一个线程,并启动。如果没有客户申请,则继续监听客户的申请。线程按客户的套接字建立输入数据流in和输数据流out。线程利用in读取客户放入线路里的信息。如果接受的信息是“结束”,则服务器回复“结束”后关闭套接字连接;否则回复:“我是服务器你对我说“,以及服务器接收到的信息

1 import java.net.*; 2 import java.io.*; 3 import java.awt.*; 4 import javax.swing.*; 5 import java.awt.event.*; 6 import java.applet.*; 7 public class Aclient extends Applet implements Runnable,ActionListener{ 8     JButton button; JTextField textF; JTextArea textA; 9     Socket socket; Thread thread;10     DataInputStream in; DataOutputStream out;11     public void init(){12         setBackground(new Color(120,153,137));13         setLayout(new BorderLayout());14         Button = new JButton(“发送信息”);15         textF = new JTextField(20);16         textA = new JTextArea(20,30);17         setSize(450,350);18         JPanel p = new JPanel();19         p.add(textF); p.add(button);20         add(textA,”Center”); add(p,”South”);21         button.addActionListener(this);22     }23     public void start(){24         try{25             socket = new Socket(this.getCodeBase().getHost(),4441);26             in = new DataInputStream(socket.getInputStream());27             out = new DataOutputStream(socket.getOutputStream());28         }catch(IOException e){}29         if(thread==null){30             thread = new Thread(this);31             thread.setPriority(Thread.MIN_PRIORITY);32             thread.start();33         }34     }35     public void run(){36         String s = null;37         while(true){38              try{39                 s = in.readUTF();40             }catch(IOException e){}41             if(s.equals(“结束”)){42                 try{43                     socket.close();break;44                 }catch(IOException e){}45             }else texA.append(s + “\n”);46         }47     }48     public void actionPerformed(ActionEvent e){49         if(e.getSource()==button){50             String s = textF.getText();51             if(s! = null){52                 try{53                     out.writeUTF(s);54                 }catch(IOException e1){}55             }56             else{57                 try{58                     out.writeUTF(“请说话”);59                 }catch(IOException e1){}60             }61        }62     }63 }

系列文章:

Java知多少(102)多媒体基础

转载于:https://www.cnblogs.com/Coda/p/4603758.html

你可能感兴趣的文章
【c学习-13】
查看>>
给报表增加页眉
查看>>
Mysql配置参数说明
查看>>
python ----字符串基础练习题30道
查看>>
K 班1-7,alpha,beta 作业成绩汇总
查看>>
uva-10879-因数分解
查看>>
清空表且自增的id重新从0开始
查看>>
[杂记]如何在LaTeX里插入高亮代码
查看>>
「常微分方程」(阿諾爾德) Page 6 問題4 經過擴張相空間的每一點有且僅有一條積分曲線...
查看>>
同一个闭区间上有界变差函数的和与积都是有界变差函数
查看>>
java安全证书配置
查看>>
使用erlang 建立一个自动化的灌溉系统(1)准备工作
查看>>
python 调用aiohttp
查看>>
mysql 案例~ mysql故障恢复
查看>>
Spring Boot中使用MyBatis注解配置详解
查看>>
MatLab实现FFT与功率谱
查看>>
答《漫话ID》中的疑问:UniqueID和ClientID的来源
查看>>
【转】Asp.net控件开发学习笔记整理篇 - 服务器控件生命周期
查看>>
Linux下的shell编程(一)BY 四喜三顺
查看>>
javascript一些小技巧
查看>>