Java网络编程

网络编程

网络编程可以让程序与网络上的其他设备中的程序进行数据交互。

网络通信基本模式

 

 实现网络编程关键的三要素

 IP地址

 

IP 地址操作类 InetAddress


实操:

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class Inet_Address {
    public static void main(String[] args) {

        InetAddress ip1 = null;
        try {
            // 1.获取本机地址对象。
            ip1 = InetAddress.getLocalHost();
            System.out.println(ip1.getHostName());
            System.out.println(ip1.getHostAddress());

            // 2.获取域名ip对象
            InetAddress ip2 = InetAddress.getByName("www.baidu.com");
            System.out.println(ip2.getHostName());
            System.out.println(ip2.getHostAddress());

            // 3.获取公网IP对象。
            InetAddress ip3 = InetAddress.getByName("112.80.248.76");
            System.out.println(ip3.getHostName());
            System.out.println(ip3.getHostAddress());

            // 4.判断是否能通: ping  5s之前测试是否可通
            System.out.println(ip3.isReachable(5000));
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

端口

 通信协议

连接和通信数据的规则被称为网络通信协议

两套参考模型

 

 

 UDP通信

 

 

 实操 UDP通信(服务器可收到多个客户端发的消息,但客户端之间不相通):

服务端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
//先启动服务端,再启动客户端!!!
//先启动服务端,再启动客户端!!!
//先启动服务端,再启动客户端!!!
//先启动服务端,再启动客户端!!!
//先启动服务端,再启动客户端!!!

public class Recive {
    public static void main(String[] args) throws IOException {
        System.out.println("==========服务端启动==========");
        // 1、创建接收端对象:注册端口
        DatagramSocket rci=new DatagramSocket(8888);
        byte[] bytes=new byte[1024*64];
        // 2、创建一个数据包对象接收数据
        DatagramPacket packet=new DatagramPacket(bytes,bytes.length);
        while (true){
            // 3、等待接收数据。
             rci.receive(packet);
            // 4、取出数据即可
            // 读取多少倒出多少
            int l=packet.getLength();
            String s=new String(bytes,0,l);
            System.out.println("服务端接收到了来自"+packet.getSocketAddress()+"端口为"+packet.getPort()+"的消息:"+s);
        }
    }
}

 客户端

import java.io.IOException;
import java.net.*;
import java.util.Scanner;
public class Send {
    public static void main(String[] args) throws IOException {
        System.out.println("==========客户端启动==========");
        System.out.println("请输入您想发送的话:");
        // 1、创建发送端对象:发送端自带默认的端口号
        DatagramSocket sd=new DatagramSocket(7777);//可在括号里指定端口号,这里Java怕你指定的端口号已被占用,所以需要抛出异常
        // 2、创建一个数据包对象封装数据
        /**
         public DatagramPacket(byte buf[], int length,
         InetAddress address, int port)
         参数一:封装要发送的数据
         参数二:发送数据的大小
         参数三:服务端的主机IP地址
         参数四:服务端的端口
         */
        Scanner scanner=new Scanner(System.in);
        byte[] bytes=new byte[1024*64];//
        while (true)
        {
            String s=scanner.next();
            if("exit".equals(s)){
                System.out.println("你已成功离线!");
                sd.close();
                break;
            }
            bytes=s.getBytes();
            DatagramPacket packet=new DatagramPacket(bytes,bytes.length, InetAddress.getLocalHost(),8888);
            // 3、发送数据出去
            sd.send(packet);
        }

    }
}

TCP通信

 

 

 

 TCP通信实操(服务器可收到多个客户端发的消息,但客户端之间不相通,利用线程池优化):

服务端

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Recive {
    public static void main(String[] args) {
        //利用线程池优化
        //创建线程池,newFixedThreadPool里的参数为线程池大小
        ExecutorService service= Executors.newFixedThreadPool(10);
        System.out.println("==========服务端启动==========");

        try {
            // 1、注册端口
            ServerSocket serverSocket=new ServerSocket(6666);
            // a.定义一个死循环由主线程负责不断的接收客户端的Socket管道连接。
            while (true){
                // 2、每接收到一个客户端的Socket管道,
                Socket socket=serverSocket.accept();
                System.out.println(socket.getRemoteSocketAddress()+"上线了!!!");
                // 任务对象负责读取消息。
                service.execute(new Recive_Thread(socket));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

 客户端

import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class Send {
    public static void main(String[] args) {
        System.out.println("==========客户端启动==========");
        System.out.println("请输入您想发送的话:");
        // 1、创建Socket通信管道请求有服务端的连接
        // public Socket(String host, int port)
        // 参数一:服务端的IP地址
        // 参数二:服务端的端口
        Scanner scanner=new Scanner(System.in);
        try {
            Socket so=new Socket("127.0.0.1",6666);
            // 2、从socket通信管道中得到一个字节输出流 负责发送数据
            OutputStream ot=so.getOutputStream();
            // 3、把低级的字节流包装成打印流
            PrintStream printStream=new PrintStream(ot);
            while (true){
                String s=scanner.nextLine();
                if("exit".equals(s))break;
                printStream.println(s);
                ot.flush();
            }
            //这里可以不关闭资源
            //ot.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 服务器接受消息的具体实现

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class Recive_Thread implements Runnable{
    private Socket socket;
    public Recive_Thread(Socket socket)
    {
        this.socket=socket;
    }
    @Override
    public void run() {

        try {
            // 3、从socket通信管道中得到一个字节输入流
            InputStream in=socket.getInputStream();
            // 4、把字节输入流包装成缓冲字符输入流进行消息的接收
            InputStreamReader ir=new InputStreamReader(in);
            BufferedReader bf=new BufferedReader(ir);
            // 5、按照行读取消息
            String s;
            while ((s=bf.readLine())!=null){
                System.out.println("服务端接收到了来自"+socket.getRemoteSocketAddress()+"端口为"+socket.getPort()+"的消息:"+s);
            }
        } catch (IOException e) {
            System.out.println(socket.getRemoteSocketAddress() + "下线了!!!");
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值