基本网络编程_第1页
基本网络编程_第2页
基本网络编程_第3页
基本网络编程_第4页
基本网络编程_第5页
已阅读5页,还剩45页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Java基本网络编程基本网络编程基于Socket的基本网络程序(1v1)利用多线程实现多客户端连接(1vN)传输对象及任何数据聊天程序设计架构Socket扩展应用示例:发邮件Socket编程编程l服务器:服务器:提供信息资源的计算机或服务器。l客户机:客户机:请求信息资源的计算机或程序。l传输协议传输协议:lTCP (Transmission Control Protocol,传输控制协议传输控制协议):“面向连接面向连接 ”,可靠的、基于字节流的传输层(Transport layer)通信协议 。如:打电话l面向连接服务要经过三个阶段:数据传数前,先建立连接先建立连接,连接建立后再传输数据传

2、输数据,数据传送完后,释放连接释放连接。面向连接服务,可确保数据传送的次序和传输的可靠性。 lUDP(User Datagram Protocol ,用户数据包协议用户数据包协议):“面向非连接面向非连接”,在正式通信前不必与对方先建立连接,不管对方状态就直接发送。如:写信l无连接服务的特点是:无连接服务只有传输数据传输数据阶段。消除了除数据通信外的其它开销。 lIP( Internet Protocol ):计算机网络相互连接网络相互连接进行通信而设计的协议。互联网地址或Internet地址。是用来唯一标识互联网上计算机的逻辑地址。 相当于电话号码。 Socke编程就是指网络编程。编程就是指

3、网络编程。OSI七层协议模型七层协议模型InetAddresslInetAddress代表了一个网络目标地址对象,封装了主机名和数字类型的地址信息。InetAddress ia=InetAddress.getLocalHost(); /获得本机获得本机IP地址情况地址情况System.out.println(主机名:+ ia.getHostName(); /得到主机名得到主机名System.out.println(“主机地址:+ ia.getHostAddress(); /得到主机地址得到主机地址InetAddress ia2=InetAddress.getByName( Lily-THINK

4、 ); /通过主机名获得信息通过主机名获得信息System.out.println(“主机地址:+ ia2.getHostAddress();InetAddress ia4=InetAddress.getByName(); /根据域名到根据域名到DNS查询查询IpSystem.out.println(163 IP:+ia4.getHostAddress();网络应用工作流程网络应用工作流程网络应用工作流程网络应用工作流程我们用我们用写信写信来举例:来举例:IP确定位置(相当于确定位置(相当于寄信的地址寄信的地址),端口确定该位置上的服务(具体是),端口确定该位置上的服务(具体是寄寄给哪个人的信

5、给哪个人的信)。)。IP可以定位到具体的计算机,端口代表计算机上提供的具体服务。可以定位到具体的计算机,端口代表计算机上提供的具体服务。IP与端口的组合得出一个套接字套接字(将应用程序和端口连接起来),达到完全分辨网络上运行的程序的作用。TCP套接字套接字为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCPIP协议交互提供了称为套接字(Socket)的接口。 Socket可以看作是通信连接两端的收发器。可以看作是通信连接两端的收发器。Socket可以看成在两个程序进行通讯连接中的通讯连接中的一个端点。一个端点。Socket所要完成的通信就是基于连接的通信,建立连接所需的程序分

6、别运行在客户端和服务器端。套接字连接就是客户端的套接字对象和服务器端的套接字对象通过输入/输出流连接在一起。套接字套接字,Socket是网是网络上运行的程序之间络上运行的程序之间双向通信链路的端点。双向通信链路的端点。TCP套接字套接字Socket部分部分通过将这3个参数个参数结合起来,与一个Socket绑定,应用层就可以和传输层通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。 在Java中,套接字(通信端点)被抽象为类,我们只需要创建Socket类的对象,就可以使用套接字。Socket中有输入输出流对象输入输出流对象,同时能实现服务器之间的数据传输数据传输。

7、一个程序(Program B )将一段信息写入Socket中,该Socket将这段信息发送给另外一个Socket(Program A)中,使这段信息能传送到其他程序中。Socket工作步骤工作步骤l建立连接建立连接1.在服务器端通过指定一个用来等待的连接的端口号创建一个 ServerSocket实例实例.2.在客户端通过主机和端口号创建一个 socket实例实例,连到服务器上.3.ServerSocket类的accept方法使服务器处于阻塞状态,等待用户请求l数据通信数据通信建立socket连接后,还应该建立输入输出数据流,客户程序可以向Socket写入请求,服务器程序处理请求,并把处理结果通

8、过Socket返回给客户端,完成通过虚拟通道的数据通信;l拆除连接拆除连接通信结束,将所建立的虚拟连接全部拆除。注意:注意:在服务器端指定的端口的时候,要注意该端口是否可用,是否已经被占用。11023已经被系统占用了,应使用102465535之间的端口号,避免发生冲突。常用网络务端口常用网络务端口 :ServerSocket和和Socket创建创建ServerSocket代表服务器端套接字。代表服务器端套接字。Socket代表客户端套接字。代表客户端套接字。ServerSocket负责监听TCP连接请求,并为每个连接创建新的Socket实例。就是说,服务端需要同时处理ServerSocket和

9、Socket,而客户端只需要使用Socket实例。创建创建ServerSocket(服务端套接字):(服务端套接字):ServerSocket(int port) 创建绑定到特定端口的服务器套接字。 ServerSocket(int port, int backlog)创建绑定到特定端口的服务器套接字,并指定最大连接数。创建创建Socket(客户端套接字):(客户端套接字):Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。Socket(String host, int port) 创建一个流套接字并将其连接到

10、指定主机上的指定端口号。发送和接受流式数据发送和接受流式数据为了能随时监听客户端的请求,可以使用accept()方法用来接收客户机程序的连接请求,返回值是一个Socket类型的对象。程序运行到这里处于等待状态。程序运行到这里处于等待状态。Socket对象创建成功后,就可以在客户机与服务器之间建立一个连接,并通过这个连接在两个端口之间传送数据。OutputStream os = socket.getOutputStream() 返回此套接字的输出流,发送数据。InputStream is = socket.getInputStream() 返回此套接字的输入流,接收数据。 下面我们创建一个“回声

11、”的例子:客户端向服务器端发送数据,然后服务器端返回客户端发送的数据。每一个Socket存在时都占用一定的资源,在通信完成后,应该断开服务器端或客户端上运行的应用程序,即断开其虚拟连接并释放所占用的系统资源。close()方法就能关闭当前套接字,释放资源。补充内容补充内容输入输出流输入输出流流操作流操作l在程序中所有的数据都是以流(Stream)的方法进行传输和保存的。l程序需要数据的时候使用输入流;l程序保存数据时使用输出流;l水流lJava把所有传统的流类型(类或抽象类)都放在java.io包中,用以实现输入输出功能。l输入和输出是一个相对的概念,我们一般站在程序的角度来分析和处理问题。l

12、读进来 -输入l写出去 -输出流的分类流的分类l从不同角度分类:l按流的方向的不同可以分为输入流和输出流;l按处理数据的单位不同分为字节流和字符流;l按功能的不同可分为节点流和处理流;l所有流都继承与以下四种抽象流类型:字节流字节流字符流字符流输入流输入流InputStreamInputStreamReaderReader输出流输出流OutputStreamOutputStreamWriterWriter字符流与字节流的区别在于前者是基于字符的操作,而后者则基于字节操作。Java里字符由两个字节组成.操作步骤操作步骤lFile类本身是与文件操作有关,但是如果要想操作内容则必须使用字节流或字符流

13、完成,但是不管是使用何种的输入输出流,其基本的操作原理是一样的(以文件流为准)l1、使用File类找到一个文件对象l2、通过字节流或字符流的子类进行对象的实例化l3、进行读或写的操作l4、关闭输入关闭输入/输出输出l由于流的操作属于资源操作,所以在操作的最后一定要关闭以释放资源。l操作流有以下几个:l字节流:OutputStream、InputStreaml字符流:Writer、Reader字节流字节流l字节流主要是操作byte的类型数据:l字节输出流:OutputStreaml字节输入流:InputStreamOutputStreamlvoid flush() throws IOExcept

14、ion:刷新缓冲区labstract void close() throws IOException:关闭输出流lvoid write(int c) throws IOException:将一个字节写入到输出流中。lvoid write(byte b) throws IOException:将一个byte数组写出。lvoid write(byte b,int off,int len) throws IOException:将字节数组从off位置开始,长度为len的字节写入到输出流中。l以其子类FileOutputStream来实例化OutputStream对象lFileOutputStream

15、(File/String file) throws FileNotFoundException创建一个向指定 File 对象表示的文件中写入数据的文件输出流。 lFileOutputStream(File/String file, boolean append) throws FileNotFoundException创建一个向指定 File 对象表示的文件中写入数据的文件输出流 OutputStream例子例子public static void main(String args) throws Exception OutputStream out = new FileOutputStrea

16、m(test.txt);out.write(hello.getBytes();out.flush();out.close();public static void main(String args) throws Exception OutputStream out = new FileOutputStream(test.txt,true);byte bys = hello.getBytes();for (int i = 0; i 0 l以其子类FileReader来实例化Reader对象lFileReader(File/String file) throws FileNotFoundExce

17、ption 创建一个向指定对象的文件输入流Reader 例子例子public static void main(String args) String path = pathName; Reader reader = null;reader = new FileReader(new File(path);/ 定义缓冲区char buf = new char50;int len = 0;/ 循环读取直到为空的时候while (len = reader.read(buf) != -1) System.out.println(new String(buf, 0, len);reader.close(

18、); Writerlabstract void flush() throws IOException:清空缓存labstract void close() throws IOException:关闭流lvoid write(char cbuf):将字符数组中的数据输入到输出流中。lvoid write(char cbuf,int off,int len):将字符数组从off位置开始,长度为len的字节输入到输出流中。lvoid write(String str):将str字符串所有字符输出到指定的输出流中。lvoid write(String str,int off, int len):将st

19、r字符串里从off位置开始,长度为len的字符输出到指定的输出流中。l以其子类FileWriter来实例化Writer对象lFileWriter(File/String file, boolean append) throws FileNotFoundException 创建一个向指定对象的文件输出流,append表示是否追加?。默认是falseWriter例子例子public static void main(String args) throws Exception Writer writer = new FileWriter(test.txt);String str = “新输入内容:你

20、好;char cbuf = str.toCharArray();/把字符串转成char数组writer.write(cbuf);/写进文件writer.flush();/刷新缓冲区writer.close();/关闭流字节流和字符流的区别字节流和字符流的区别l字节流和字符流在使用上的代码结构都是非常类似的,但是其内部本身也是有区别的,因为在进行字符流操作的时候会使用到缓冲区,而字节流操作的时候是不会使用到缓冲区的。l在输出的时候,OutputStream类即使最后没有关闭内容也可以输出。但是如果是Writer的话,则如果不关闭,最后一条内容是无法输出的,因为所有的内容都是保存在了缓冲区之中,每

21、当调用了close()方法就意味着清空缓冲区了。那么可以证明字符流确实使用了缓冲区:l字节流:程序 文件l字符流:程序 缓冲区 文件l如果现在字符流字符流即使不关闭也可以完成输出的话,则必须强制性清空缓冲区:l方法:public void flush() throws IOExceptionl两者相比,肯定使用字节流更加的方便,而且在程序中像图片、MP3等都是采用字节的方式的保存,那么肯定字节流会比字符流使用的更广泛。l但是需要说明的是,如果要是想操作中文的话,字符流肯定是最好使的。字节字节字符转换流字符转换流lOutputStreamWriter:Writer子类,把字节输出流对象转成字符输

22、出流对象lInputStreamReader:Reader子类,把字节输入流对象转成字符输入流对象lFileWriter和FileReader分别是OutputStreamWriter和InputStreamReader的直接子类,而不是Writer和Reader的直接子类,区别于FileInputStream 和InputStream。l注:无论使用字节流还是字符流实际上最终都是通过字节的形式来操作流的。例子例子/构建一个字节输出流对象OutputStream out = new FileOutputStream();/把字节输出流转成字符输出流Writer w = new OutputSt

23、reamWriter(out);/然后的操作和使用字符输出流的操作一样-/构建一个字节输入流对象InputStream is = new FileInputStream();/把字节输入流转成字符输入流Reader r = new InputStreamReader(is);/然后的操作和使用字符输入流的操作一样lBufferedReader/BufferedWriter提供了支持缓冲区的流数据读写BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream();BufferedWriter

24、 bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream();l向流中一次写一行,可用PrintWriter类将原来的流改造成新的打印流,PrintWriter类有一个方法println(),能一次输出一行。如: l.lPrintWriter out = new PrintWriter(new BufferedWriter(l new FileWriter(D:javacodetest.txt);lout.println(Hello World!);lout.close();l.创建服务器端创建服务器端创建服务

25、器端创建服务器端public class EchoServer ServerSocket serverSocket;private final int PORT=8888; /端口端口public EchoServer() throws IOExceptionserverSocket=new ServerSocket(PORT); /创建服务器端套创建服务器端套接字接字System.out.println(服务器启动。);/servic()方法方法public static void main(String args) throws IOException new EchoServer().s

26、ervic(); /启动服务启动服务Servicepublic void servic()Socket socket=null;while(true)try socket = serverSocket.accept(); /等待并取出用户连接,并创建套接字等待并取出用户连接,并创建套接字System.out.println(新连接,连接地址:+socket.getInetAddress()+:+socket.getPort(); /客户客户端信息端信息/输入流,读取客户端信息输入流,读取客户端信息BufferedReader br=new BufferedReader(new InputStr

27、eamReader(socket.getInputStream(); /输出流,向客户端写信息输出流,向客户端写信息BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(); PrintWriter pw=new PrintWriter(bw,true); /装饰输出流,装饰输出流,true,每写一行就刷新输出缓冲区,不用每写一行就刷新输出缓冲区,不用flushString info=null; /接收用户输入的信息接收用户输入的信息while(info=br.readLine()!

28、=null) System.out.println(info); /输出用户发送的消息输出用户发送的消息pw.println(you said:+info); /向客户端返回用户发送的消息,向客户端返回用户发送的消息,println输出完后会自动刷新输出完后会自动刷新缓冲区缓冲区if(info.equals(quit) /如果用户输入如果用户输入“quit”就退出就退出 break; /如果客户端断开连接,则应捕获该异常,但不应中断整个如果客户端断开连接,则应捕获该异常,但不应中断整个while循环,使得服务器能继续与其他客户循环,使得服务器能继续与其他客户端通信端通信 catch (IOEx

29、ception e) e.printStackTrace();finallyif(null!=socket)try socket.close(); /断开连接断开连接 catch (IOException e) e.printStackTrace();创建客户端创建客户端创建客户端创建客户端public class EchoClient static final int PORT=8888; /连接端口连接端口static final String HOST=; /连接地址连接地址Socket socket;public EchoClient() throws Unkno

30、wnHostException, IOExceptionsocket=new Socket(HOST,PORT); /创建客户端套接字创建客户端套接字/send()方法方法public static void main(String args) throws UnknownHostException, IOException new EchoClient().send(); sendpublic void send() try /客户端输出流,向服务器发消息客户端输出流,向服务器发消息BufferedWriter bw=new BufferedWriter(new OutputStreamWr

31、iter(socket.getOutputStream();/客户端输入流,接收服务器消息客户端输入流,接收服务器消息BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream();PrintWriter pw=new PrintWriter(bw,true); /装饰输出流,及时刷新装饰输出流,及时刷新Scanner in=new Scanner(System.in); /接受用户信息接受用户信息String msg=null;while(msg=in.next()!=null)pw.pri

32、ntln(msg); /发送给服务器端发送给服务器端System.out.println(br.readLine(); /输出服务器返回的消息输出服务器返回的消息if(msg.equals(quit)break; /退出退出 catch (IOException e) e.printStackTrace();finallyif(null!=socket)try socket.close(); /断开连接断开连接 catch (IOException e) e.printStackTrace();测试测试可以看到,服务器端显示客户端套接字的地址和本机一致,端口为52877由操作系统随即产生的,在

33、客户端每创建一个Socket对象,操作系统就会为客户分派一个端口。在编写在编写Socket程序时,只需要显式的为服务器程序中的程序时,只需要显式的为服务器程序中的ServerSocket设置端设置端口,客户端的端口不必关心。口,客户端的端口不必关心。一个客户端退出,另外一个才能和服务器连接一个客户端退出,另外一个才能和服务器连接启动客户端进程/Server端程序,接收用户数据,回传客户端数据import java.io.*;import .*;public class JabberServer / Choose a port outside of the range 1-1024: publi

34、c static final int PORT = 8080; public static void main(String args) throws IOException ServerSocket s = new ServerSocket(PORT); System.out.println(Started: + s); try / Blocks until a connection occurs: Socket socket = s.accept(); try System.out.println(Connection accepted: + socket); BufferedReader

35、 in = new BufferedReader( new InputStreamReader(socket.getInputStream(); / Output is automatically flushed by PrintWriter: PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),true); while (true) String str = in.readLine(); if (str.equals(END) break; S

36、ystem.out.println(Echoing: + str); out.println(str); / Always close the two sockets. finally System.out.println(closing.); socket.close(); finally s.close(); /客户端程序import .*;import java.io.*;public class JabberClient public static void main(String args) throws IOException InetAddress addr = InetAddr

37、ess.getByName(null); System.out.println(addr = + addr); Socket socket = new Socket(addr, JabberServer.PORT); try System.out.println(socket = + socket); BufferedReader in =new BufferedReader(new InputStreamReader(socket.getInputStream();PrintWriter out = new PrintWriter(new BufferedWriter(new OutputS

38、treamWriter(socket.ge tOutputStream(),true); for(int i = 0; i 10; i +) out.println(howdy + i); String str = in.readLine(); System.out.println(str); out.println(END); finally System.out.println(closing.); socket.close(); 问题:l一个服务器只为一个客户端服务l服务端与客户端必需严格一问一答import java.io.*;import .*;class ServeOneJabbe

39、r 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( ne

40、w 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();

41、 if (str.equals(END) break; System.out.println(Echoing: + str); out.println(str); System.out.println(closing.); catch(IOException e) System.err.println(IO Exception); finally try socket.close(); catch(IOException e) System.err.println(Socket not closed); public class MultiJabberServer static final i

42、nt PORT = 8080; public static void main(String args) throws IOException ServerSocket s = new ServerSocket(PORT); System.out.println(Server Started); try while(true) Socket socket = s.accept(); try new ServeOneJabber(socket); catch(IOException e) socket.close(); finally s.close(); 传输对象传输对象public clas

43、s User implements java.io.Serializable private static final long serialVersionUID = 1L; private String name; private String password; public User() public User(String name, String password) = name; this.password = password; /此处省略setName getName setPassword getPassword定义 传输对象传输对象public class MyServer private final static Logger logger = Logger.getLogger(MyServer.class.getName(); public static void main(String args) throws IOException ServerSocket s

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论