网络编程:IP地址InetAddress,URL统一资源定位器/符,编码和解码,实现客户端与服务器端一次通信,客户端与服务器端实现一次双向通信 ,实现一次双向通信,使用UDP实现两人多次聊天

21.七层协议与四层协议
  21.1七层协议 OSI
         应用层-->表示层-->会话层-->传输层-->网络层-->数据链路层->物理层
         四层协议  TCP/IP协议  传输控制协议/网络互连协议
          应用层(http, ftp)----------------------->传输层(tcp,udp)->网络层--->网络接口

  21.2数据的封装与拆封
      发送方-->数据封装
      接收方-->数据拆封

  21.3网络编程的三要素
        (1)IP地址
        (2)端口
        (3)协议

21.4IP地址InetAddress

package com.bjsxt.net;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class TestInetAddress {
        public static void main(String[] args) throws UnknownHostException {
                //(1)获取InetAddress对象
                InetAddress ia=InetAddress.getByName("110-SHEYANG");//主机就是本机
                System.out.println(ia);  //说明重写了toString()方法
                System.out.println("主机名称:"+ia.getHostName());
                System.out.println("主机IP地址:"+ia.getHostAddress());
                
                InetAddress ia2=InetAddress.getByName("www.baidu.com"); //百度的IP地址
                System.out.println(ia2);
                
                
        }
}

21.5URL统一资源定位器/符

package com.bjsxt.net;

import java.net.MalformedURLException;
import java.net.URL;

public class TestURL {
        public static void main(String[] args) throws MalformedURLException {
                URL u=new URL("https://www.baidu.com");
                System.out.println(u);  //重写了toString方法()
                System.out.println("网址"+u.getHost()); //网址
                //System.out.println(u.getPath());获取路径
                //System.out.println(u.getPort());  //-1
                System.out.println("协议"+u.getProtocol());//http
                
                
        }
}

21.6编码和解码

package com.bjsxt.net;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

public class EndorAnd {
        public static void main(String[] args) throws UnsupportedEncodingException {
                //编码
                String str=URLEncoder.encode("尚学堂", "utf-8");
                System.out.println(str);
                //解码
                String ss=URLDecoder.decode(str, "utf-8");
                System.out.println(ss);
        }
}

建立两个项目 
 (1)客户端项目
         发送请求    -->OutputStream 

 (2)服务器端项目
         接收请求   -->InputStream

21.7.1实现客户端与服务器端一次通信,  客户端向服务器发送一句话 helloworld

客户端

package com.bjsxt.client;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Cleint {
        public static void main(String[] args) throws UnknownHostException, IOException {
                //(1)创建Socket对象,主机,和(服务器端)端口
                Socket client=new Socket("192.168.45.241", 9000);
                //(2)获取输出流
                OutputStream os=client.getOutputStream();  //目的地是192.168.45.241服务器中端口为9000的应用程序
                /*//(3)使用处理流处理下
                DataOutputStream dos=new DataOutputStream(os);
                //(4)发送
                dos.writeUTF("你好!");*/
                os.write("helloworld!".getBytes());
                
                //关闭
                os.close();
                client.close();
        }
}

服务器端:

package com.bjsxt.server;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
        public static void main(String[] args) throws IOException {
                System.out.println("服务器端已开启..................");
                //(1)创建ServerSocket对象
                ServerSocket server=new ServerSocket(9000);//我在9000等你(客户端)
                //(2)监听客户端的请求
                Socket s=server.accept();  //监听到一个Socket对象 (客户端)
                //(3)接收
                InputStream is=s.getInputStream();
                byte [] b=new byte[1024];
                int length=0;//读到的字节的个数
                while((length=is.read(b))!=-1){
                        System.out.println(s.getInetAddress().getHostAddress()+"--->"+new String(b,0,length));
                }
                //(4)关闭
                s.close();
                server.close();
                
        }
}

27.7.2客户端与服务器端实现一次双向通信 模拟用户登录

两个项目
  要求:实体类的包名,必须完全相同
  (1)实体类  要求:客户端与服务器端的包名,完全相同,
                            客户端的实体类中的属性与服务器端实体类的属性要求完全相同

  (2)客户端
           1.创建Socket对象
        发送
           2.获取输出流
           3.发送数据
           4.截断输出流
       接收
            5.获取输入流
            6.接收数据
            7.截断输入流
            
         8.关闭所有流
客户端:

package com.bjsxt.client;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

import com.bjsxt.entity.User;

public class CleintLogin {
        public static void main(String[] args) throws UnknownHostException, IOException {
                /***用于向服务器发送请求*/
                Socket client=new Socket("192.168.45.241", 9000);
                //使用输出流
                ObjectOutputStream oos=new ObjectOutputStream(client.getOutputStream());
                //发送对象
                oos.writeObject(getUser());  //调用本类中的获取用户对象方法
                client.shutdownOutput();//截断输出流
                /**接收来自服务器的响应*/
                DataInputStream dis=new DataInputStream(client.getInputStream());
                System.out.println(dis.readUTF());
                //截断输入流
                client.shutdownInput();
                //关闭
                dis.close();
                oos.close();
                client.close();
                
        }
        //获取用户对象
        public static User getUser(){
                Scanner input=new Scanner(System.in);
                System.out.println("请输入用户名:");
                String userName=input.next();
                System.out.println("请输入密码:");
                String password=input.next();
                return new User(userName, password);
        }
}

(3)服务器端
            1.创建ServerSocket对象
             2.监听来自客户端的请求
         接收
            3.获取输入流
            4.接收数据 并验证
            5.截断输入流

       发送
          6.获取输出流
          7.发送数据
           8.截断输出流

         9.关闭所有流

package com.bjsxt.server;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;

import com.bjsxt.entity.User;

public class ServerLogin {
        public static void main(String[] args) throws IOException, ClassNotFoundException {
                System.out.println("服务器已开启............");
                /**(1)接收来自客户端的请求*/
                ServerSocket server=new ServerSocket(9000);
                 //服务器监听
                Socket client=server.accept();
                //接收用户对象
                ObjectInputStream ois=new ObjectInputStream(client.getInputStream());
                User user=(User)ois.readObject();
                System.out.println("IP地址为:"+client.getInetAddress().getHostAddress()+"请求登录");
                //截断输入流
                client.shutdownInput();
                //登录的用户名和密码验证
                String result=null;
                if("bjsxt".equals(user.getUserName())&&"bjsxt".equals(user.getPassword())){
                        result="登录成功";
                }else{
                        result="对不起,账号或密码不存在!";
                }
                /**(2)对客户端的请求作出响应,发送给客户端*/
                DataOutputStream dos=new DataOutputStream(client.getOutputStream());
                dos.writeUTF(result);
                //截断输出流
                client.shutdownOutput();
                //关闭
                dos.close();
                ois.close();
                client.close();
                server.close();
                
        }
}

TCP:
   面向连接,可靠的,基于IO流的编程
   效率低,安全性高(三次握手)
    启动有先后,一定先启服务器,再启客户端,连接成功,谁先发送信息都可以
  常见问题
(1)连接被拒绝   (检查IP地址,端口号,关闭防火墙)

(2)端口被占用

(3)连接超时  time out...
IP 地址不通,或IP地址写错,防火墙

UDP:面向无连接   不可靠的,基于数据报/包的编程

接收方和发送方  地位是平等

21.8UDP编程
21.8.1一次单向通信
发送方

package com.bjsxt.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class TestSend {
        public static void main(String[] args) throws IOException {
                //(1)创建接收和发送的对象
                DatagramSocket ds=new DatagramSocket();
                //(2)需要对数据进行打包
                byte [] buf="helloworld".getBytes();
                DatagramPacket dp=new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.45.241"), 9000);
                //(3)发送
                ds.send(dp);
                //(4)关
                
                ds.close();
                
        }
}

接收方

package com.bjsxt.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class TestReceive {  //接收方
        public static void main(String[] args) throws IOException {
                //(1)用于发送和接收,  接收
                DatagramSocket ds=new DatagramSocket(9000);//我在9000等你
                //(2)创建包裹,准备接收
                byte [] buf=new byte[1024];
                DatagramPacket dp=new DatagramPacket(buf, buf.length);
                ds.receive(dp);//接收
                //(3)查看收到的内容
                System.out.println(new String(dp.getData(),0,dp.getLength()));
                
                //(4)关闭
                ds.close();
        }
}

21.8.2实现一次双向通信
先发送,后接收

package com.bjsxt.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class TestSend2 {
        public static void main(String[] args) throws IOException {
                //(1)创建接收和发送的对象
                DatagramSocket ds=new DatagramSocket();
                /**发送*/
                //(2)需要对数据进行打包
                byte [] buf="helloworld".getBytes();
                DatagramPacket dp=new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.45.241"), 9000);
                //(3)发送
                ds.send(dp);
                /**发送完毕*/
                //(4)关
                /**接收*/
                
                byte [] buf2=new byte[1024];
                DatagramPacket dp2=new DatagramPacket(buf2, buf2.length);
                ds.receive(dp2);
                System.out.println(new String(dp2.getData(),0,dp2.getLength()));
                
                
                ds.close();
                
        }
}

先接收,后发送

package com.bjsxt.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class TestReceive2 {  //接收方
        public static void main(String[] args) throws IOException {
                //(1)用于发送和接收,  接收
                DatagramSocket ds=new DatagramSocket(9000);//我在9000等你
                /**接收数据*/
                //(2)创建包裹,准备接收
                byte [] buf=new byte[1024];
                DatagramPacket dp=new DatagramPacket(buf, buf.length);
                ds.receive(dp);//接收
                //(3)查看收到的内容
                System.out.println(new String(dp.getData(),0,dp.getLength()));
                /***接收完毕*/
                /**回复对方*/
                byte [] buf2="welcomce to beijing".getBytes();
                DatagramPacket dp2=new DatagramPacket(buf2, buf2.length, dp.getAddress(), dp.getPort());
                
                ds.send(dp2);
                //(4)关闭
                ds.close();
        }
}

21.8.3使用UDP实现两人多次聊天  --循环

package com.bjsxt.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class TestSend3 {
        public static void main(String[] args) throws IOException {
                Scanner input=new Scanner(System.in);
                //(1)创建接收和发送的对象
                DatagramSocket ds=new DatagramSocket();
                while(true){
                        /**发送*/
                        //(2)需要对数据进行打包
                        String s=input.next();//从键盘接收一句话
                        byte [] buf=s.getBytes();
                        DatagramPacket dp=new DatagramPacket(buf, buf.length, InetAddress.getByName("192.168.45.241"), 9000);
                        //(3)发送
                        ds.send(dp);
                        /**发送完毕*/
                        //(4)关
                        /**接收*/
                        
                        byte [] buf2=new byte[1024];
                        DatagramPacket dp2=new DatagramPacket(buf2, buf2.length);
                        ds.receive(dp2);
                        System.out.println(new String(dp2.getData(),0,dp2.getLength()));
                        if ("bye".equals(s)) {
                                break;
                        }
                        
                }
                
                ds.close();
                
        }
}
package com.bjsxt.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Scanner;

public class TestReceive3 {  //接收方
        public static void main(String[] args) throws IOException {
                Scanner input=new Scanner(System.in);
                //(1)用于发送和接收,  接收
                DatagramSocket ds=new DatagramSocket(9000);//我在9000等你
                
                while(true){
                        /**接收数据*/
                        //(2)创建包裹,准备接收
                        byte [] buf=new byte[1024];
                        DatagramPacket dp=new DatagramPacket(buf, buf.length);
                        ds.receive(dp);//接收
                        //(3)查看收到的内容
                        System.out.println(new String(dp.getData(),0,dp.getLength()));
                        /***接收完毕*/
                        /**回复对方*/
                        String s=input.next();
                        byte [] buf2=s.getBytes();
                        DatagramPacket dp2=new DatagramPacket(buf2, buf2.length, dp.getAddress(), dp.getPort());
                        
                        ds.send(dp2);
                        if ("bye".equals(s)) {
                                break;
                        }
                }
                //(4)关闭
                ds.close();
        }
}

猜你喜欢

转载自blog.csdn.net/wyqwilliam/article/details/81839725