Java网络编程

来源:互联网 发布:跨区域淘宝客服招聘 编辑:程序博客网 时间:2024/06/03 16:37


网络模型

一、分类

可分为OSI参考模型和TCP/IP参考模型如下图所示:

 

二、通信

网络通信三要素:IP地址,端口号,传输协议

IP地址:

        1、它是网络中的设备标识

        2、不易记忆,可用主机名表示,两者存在映射关系

        3、本机回环地址:127.0.0.1,主机名为:localhost。

IP地址:java中对应的是InetAddress类,存在于java.net包中。

端口号:

用于标识进程的逻辑地址,不用进程的标识。可分为物理端口和逻辑端口。

逻辑端口:用于标识进程的逻辑地址,不同进程的标识;有效端口:0~65535,其中0~1024系统使用或保留端口。

传输协议:

        即通信规则,包含TCP和UDP协议

通信数据传输示意图如下:

 

传输协议

一、Socket:

套接字,通信的端点。

就是为网络服务提供的一种机制,通信的两端都有Socket,网络通信其实就是Socket间的通信,数据在两个Socket间通过IO传输。

二、UDP协议

1、概述

是面向无连接,明确了对方的端口,无论在不在网上,只管传输,不在就会丢失数据。只求速度,应用于网络视频会议和聊天等应用程序中。

2协议特点:

         a、面向无连接,即将数据及源和目的封装成数据包中,不建立链接的发送

         b、每个数据包的大小限制在64K之内

         c、因无连接,是不可靠的协议

         d、不建立连接,速度快。

3、传输方法:

        1)创建 UDPSocket发送服务对象:

              DatagramSocket(),不指定端口。DatagramSocket(int port),指定端口。

        2)发送:void send(DatagramPacket p)

        3)接收:void receive(DatagramPacket p)

注意:直接操作udp不可能,对于java语言应该将udp封装成对象,易于我们的使用,这个对象就是DatagramSocket. 封装了udp传输协议的socket对象。

因为数据包中包含的信息较多,为了操作这些信息方便,也一样会将其封装成对象。这个数据包对象就是:DatagramPacket.通过这个对象中的方法,就可以获取到数据包中的各种信息。

DatagramSocket具备发送和接受功能,在进行udp传输时,需要明确一个是发送端,一个是接收端。

4、udp的发送端工作流程:

1,建立udp的socket服务,创建对象时如果没有明确端口,系统会自动分配一个未被使用的端口。

2,明确要发送的具体数据。

3,将数据封装成了数据包。

4,用socket服务的send方法将数据包发送出去。

5,关闭资源。

示例:

import java.net.*;class  UdpSend{public static void main(String[] args)throws Exception {// 1,建立udp的socket服务。DatagramSocket ds = new DatagramSocket(8888);//指定发送端口,不指定系统会随机分配。// 2,明确要发送的具体数据。String text = "udp传输演示 哥们来了";byte[] buf = text.getBytes();// 3,将数据封装成了数据包。DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("10.1.31.127"),10000);// 4,用socket服务的send方法将数据包发送出去。ds.send(dp);// 5,关闭资源。ds.close();}}

5、udp的接收端工作流程:

1,创建udp的socket服务,必须要明确一个端口,作用在于,只有发送到这个端口的数据才是这个接收端可以处理的数据。

2,定义数据包,用于存储接收到数据。

3,通过socket服务的接收方法将收到的数据存储到数据包中。

4,通过数据包的方法获取数据包中的具体数据内容,比如ip、端口、数据等等。

5,关闭资源。

示例:

class UdpRece {public static void main(String[] args) throws Exception{// 1,创建udp的socket服务。DatagramSocket ds = new DatagramSocket(10000);// 2,定义数据包,用于存储接收到数据。先定义字节数组,数据包会把数据存储到字节数组中。byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);// 3,通过socket服务的接收方法将收到的数据存储到数据包中。ds.receive(dp);//该方法是阻塞式方法。// 4,通过数据包的方法获取数据包中的具体数据内容,比如ip,端口,数据等等。String ip = dp.getAddress().getHostAddress();int port = dp.getPort();String text = new String(dp.getData(),0,dp.getLength());//将字节数组中的有效部分转成字符串。System.out.println(ip+":"+port+"--"+text);// 5,关闭资源。ds.close();}}


三、TCP协议

1、概述

是面向连接的,必须连接成功才能传输数据,应用于下载等程序上

2协议特点

         1面向连接,在建立连接后,形成传输数据的通道

         2在连接中进行大数据量的传输

         3)通过三次握手完成连接,是可靠的协议

         4必须建立连接,效率稍慢

三次握手:第一次本方发送请求,第二次对方确认连接,第三次本方再次确认连接成功。

3、通信的步骤:

        1)找到IP地址

        2)数据要发送到对象指定应用程序,为标识这些应用程序,所以给这些网络应用程序都用数字标识,为方便称呼这个数字,叫做端口,即逻辑端口。

        3)定义通信规则,称之为协议。国际组织定义了通用协议,即TCP/IP。

注意:必须要有数字标识才能将数据发送到应用程序上。

4、数据传输

两个端点的建立连接后会有一个传输数据的通道,这通道称为流,而且是建立在网络基础上的流,称之为socket流。该流中既有读取,也有写入。

tcp的两个端点:一个是客户端,一个是服务端。

客户端:对应的对象,Socket

服务端:对应的对象,ServerSocket

 

TCP客户端工作流程:

1,建立tcp的socket服务,最好明确具体的地址和端口。这个对象在创建时,就已经可以对指定ip和端口进行连接(三次握手)。

2,如果连接成功,就意味着通道建立了,socket流就已经产生了。只要获取到socket流中的读取流和写入流即可,只要通过getInputStream和getOutputStream就可以获取两个流对象。

3,关闭资源。

示例:

import java.net.*;import java.io.*;//需求:客户端给服务器端发送一个数据。class  TcpClient{public static void main(String[] args) throws Exception{Socket s = new Socket("10.1.31.69",10002);OutputStream out = s.getOutputStream();//获取了socket流中的输出流对象。out.write("tcp演示,哥们又来了!".getBytes());s.close();}}


TCP服务端工作流程:

1,创建服务端socket服务,并监听一个端口。

2,服务端为了给客户端提供服务,获取客户端的内容,可以通过accept方法获取连接过来的客户端对象。

3,可以通过获取到的socket对象中的socket流和具体的客户端进行通讯。

4,如果通讯结束,关闭资源。注意:要先关客户端,再关服务端。

示例:

class  TcpServer{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10002);//建立服务端的socket服务Socket s = ss.accept();//获取客户端对象String ip = s.getInetAddress().getHostAddress();System.out.println(ip+".....connected");// 可以通过获取到的socket对象中的socket流和具体的客户端进行通讯。InputStream in = s.getInputStream();//读取客户端的数据,使用客户端对象的socket读取流byte[] buf = new byte[1024];int len = in.read(buf);String text = new String(buf,0,len);System.out.println(text);// 如果通讯结束,关闭资源。注意:要先关客户端,在关服务端。s.close();ss.close();}} 


应用案例

一、实现客户端的并发登录

设计需求:

1客户端通过键盘录入用户名,服务端对这个用户名进行校验。

2如果该用户存在,在服务端显示xxx,已登陆;并在客户端显示xxx,欢迎光临。

       3如果用户不存在,在服务端显示xxx,尝试登陆;并在客户端显示xxx,该用户不存在。

       4最多就登录三次。

设计代码:

import java.io.*;import java.net.*;//客户端class  LoginClient{public static void main(String[] args) throws Exception{//创建服务Socket s=new Socket("localhost",10000);//键盘录入BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); //用Socket服务输出流写入数据PrintWriter out =new PrintWriter(s.getOutputStream(),true ); //接收服务器返回的信息BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream())); String line=null; for(int x=0;x<3;x++){line=br.readLine();//读取键盘录入if (line==null){break;//如果键盘没有输入,则直接结束} out.println(line);//将数据写入流中 String info=in.readLine();//读取返回信息 System.out.println(info); if (info.contains("欢迎"))//---------------{break;//如果登录成功,就跳出循环}} br.close();//关流s.close();}} //服务端class LoginServer{public static void main(String [] args)throws Exception{//创建服务,监听端口ServerSocket ss=new ServerSocket(10000);while (true){//获取客户端对象Socket s=ss.accept();//客户端执行线程new Thread(new LoginThread(s)).start();}//ss.close();}} //利用多线程实现并发登录class LoginThread implements Runnable{private Socket s;LoginThread(Socket s){this.s=s;}public void run(){//获取客户端ipString ip=s.getInetAddress().getHostAddress();System.out.println(ip+"  connected.....");try{for (int x=0;x<3 ;x++ ){//通过客户端的读取流读取数据BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream()));//读取数据库中的数据,这里用文件来表示数据库BufferedReader br=new BufferedReader(new FileReader("users.txt")); String line=in.readLine();//读取客户端数据if (line==null)//--------------{break;//如果客户端没有发送数据,则跳出循环}String data=null;boolean flag=false;//设置标记//读取数据库中的用户数据while ((data=br.readLine())!=null){if (line.equals(data)){flag=true;//如果用户存在,则将标记设为truebreak;}} //将数据写入到指定文件中PrintWriter out=new PrintWriter(s.getOutputStream(),true); if (flag){System.out.println(line+",已登陆!");out.println(line+",欢迎光临!"); break;//-----------}else{System.out.println(line+",尝试登陆!");out.println(line+",用户名不存在!");}}s.close();//关流}catch (Exception e){throw new RuntimeException("用户登陆失败");}}} 


二、实现URL连接

示例:

import java.net.*;  import java.io.*;    /**URLConnection 抽象类是所有类的超类,它代表应用程序和URL之间的通信链接,此类的实例可用于读取和写入此URL引用的资源,通常,创建一个到URL的            连接需要几个步骤。      * 1,通过在URL,上调用openConnection()方法创建连接对象,      * 2,处理设置参数和一般请求属性      * 3,使用connect方法建立到远程对象的实际连接,      * 4,远程对象变为可用,远程对象的头字段和内容变为可访问。      * URLConnection openConnection()返回一个URLConnection对象,它表示到URL所引用的远程对象的连接。      * InputStream getInputStream()返回从此打开的连接读取的输入流。             * InputStream openStream()打开到此URL的连接并返回一个用于从该连接读入的InputStream      * @param args      */   public class URLConnectionDemo {        public static void main(String[] args) throws Exception      {          URL url=new URL("http://192.68.1.123:8080/myweb/demo.html");                    URLConnection conn=url.openConnection();                    System.out.println(conn);                    InputStream in=conn.getInputStream();                    byte[]buf=new byte[1024];                    int len=in.read(buf);                    System.out.println(new String(buf,0,len));      }  }    



0 0
原创粉丝点击