java-网络编程

网络编程

1.网络编程的定义

  • 在网络通信协议下,实现网络互联的不同计算机上运行的程序间可以进行数据交换

1.2 网络编程的三要素

  • IP地址:计算机的标识符
  • 端口:应用程序的标识符
  • 协议:计算机之间连接和通信的规则

1.3 IP地址

  • ipv4:32bit地址,一般用10进制点表示法,例如:192.168.1.1

  • ipv6:128bit地址,8组十六进制数组成

1.4 Inet Address类

  • 此类表示Internet协议(IP)地址

  • 相关方法

方法名说明
static inetAddress getByName(String host)确定主机名称的ip地址
String getHostName()获取此IP地址的主机名
String getHostAddress()返回文本显示的IP地址字符串
示例
package 网络编程;

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

public class Demo {
    public static void main(String[] args) throws UnknownHostException {

//        1.根据ip地址创建对象
        InetAddress id = InetAddress.getByName("192.168.142.1");
//         2.获取主机名

        String hostName = id.getHostName();
        System.out.println(hostName);

//        3.返回文本显示的ip字符串

        System.out.println(id.getHostAddress());

    }
}

  • 效果图

在这里插入图片描述

1.5 UDP和TCP协议

UDP
  • 无连接通信协议,发送端和接收端不产生逻辑链接,发送端不会确认接收端的存在,发送数据报,接收端接收数据也不会有反馈
Tcp
  • 传输控制协议
  • 三次握手

2. java的UDP通信

  • DategramSocket类

  • 构造方法

方法名说明
DategramSocket()创建数据报文绑定到本地地址的任何可用端口
DategramPacket(byte[] buf,int length,InetAddress address,int port)构造一个数据包,发送长度为 length的数据包到指定主机上的指定端口号。
  • 相关方法
方法名说明
void send(DatagramPacket p)发送数据报包
void close()关闭数据报套接字
void receive(DatagramPacket p)接收数据报包
发送数据
  1. 创建DategramSocket对象
  2. 创建数据,打包(DategramPacket)
  3. 调用DategramSocket的send方法
  4. 关闭发送端
package 网络编程;

import java.io.IOException;
import java.net.*;

public class sendDemo {
    public static void main(String[] args) throws IOException {
//        1.创建DatagramSocket 对象
        DatagramSocket ds = new DatagramSocket();

//        2.创建数据

        byte []bys="hello world".getBytes();

//        3.创建DatagramPacket对象

        DatagramPacket dp = new DatagramPacket(bys,bys.length, InetAddress.getByName("192.168.142.1"),12345);
//        4.调用send方法
        ds.send(dp);

    }
}

接收数据
  • 构造方法
方法名说明
DategramPacket(byte[] buf,int len)创建一个DategramPacket用于接收长度为len的数据包
  • 相关方法
方法名说明
byte[] getData()返回数据缓冲区
int getLength()返回要发送数据的长度或接收数据的长度
package 网络编程;

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

public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
//        1.创建接收数据包的DatagramSocket对象

        DatagramSocket ds = new DatagramSocket(12345);

//        2.创建接收数据包

        byte[] bys = new byte[1024];

        DatagramPacket dp = new DatagramPacket(bys,bys.length);

//      3.调用接收方法
        ds.receive(dp);

        System.out.println(new String(dp.getData(),0,dp.getLength()));

//        4.关闭接收端

        ds.close();

    }
}

  • 效果图

在这里插入图片描述

接收和发送数据练习
  • 接收端一直接收数据

  • 发送端当键盘输入为886时停止发送

  • 发送端

package 网络编程.udp通信练习;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class SendDemo {
    public static void main(String[] args) throws IOException {

//        1.创建发送Ds

        DatagramSocket ds = new DatagramSocket();

//        发送数据来自键盘输入,知道键盘输入为886才停止发送

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String str;



        while((str=br.readLine())!=null){
            if(str.equals("886")){
                break;
            }else{
//                3.创建发送数据包

                byte[] bys=str.getBytes();

                DatagramPacket dp = new DatagramPacket(bys,bys.length, InetAddress.getByName("10.152.242.223"),12345);

                ds.send(dp);


            }
        }

        ds.close();

    }
}

  • 接收端
package 网络编程.udp通信练习;

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

public class ReceiveDemo {
    public static void main(String[] args) throws IOException {
//        1.创建接收DatagramSocket
        DatagramSocket ds = new DatagramSocket(12345);


//        2.创建接收数据包
        while(true){
            byte[] bys = new byte[1024];
            DatagramPacket dp = new DatagramPacket(bys,bys.length);

//        3.调用接收方法
            ds.receive(dp);

//            4.输出数据

            System.out.println(new String(dp.getData(),0,dp.getLength()));

        }




    }
}

  • 效果图

在这里插入图片描述

3. java的TCP通信程序

  • java为客户端提供了Socket类,为服务器提供了ServerSocket类

3.1 tcp发送数据

  • 构造方法
方法名说明
Socket(InetAddress address,int port)创建流套接字并将其连接到指定IP指定端口号
Socket(String host,int port)创建流套接字并将其连接到指定主机的指定端口号
  • 相关方法
方法名说明
InputStream getInputStream()返回此套接字的1输入流
OutputStream getOutputStream()返回此套接字的输出流

3.2 tcp接收数据(服务端)

  • 构造方法
方法名说明
ServletSocket(int port)创建绑定到指定端口的服务器套接字
  • 相关方法
方法名说明
Socket accept()监听要连接到此套接字并接收它
客户端
package 网络编程.tcp通信;

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

public class ClientDemo {
    public static void main(String[] args) throws IOException {
//        1.创建客户端的tcp通信
        Socket s = new Socket("10.152.242.223", 12345);

//        2.获取输出流

        OutputStream os = s.getOutputStream();

//        3.写数据
        os.write("hello.world".getBytes());

        s.close();

    }
}

服务端
package 网络编程.tcp通信;

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

public class ServerDemo {
    public static void main(String[] args) throws IOException {
//        1.服务器端

        ServerSocket ss= new ServerSocket(12345);

//        2.获取输入流

//        使用ss.accept()方法连接此套接字并接收

        Socket s = ss.accept();
//          获取输入流
        InputStream is = s.getInputStream();

        byte[] bys = new byte[1024];
        int len;
        while((len=is.read(bys))!=-1){
            String s1 = new String(bys, 0, len);
            System.out.println("接收的数据为"+s1);
        }

        s.close();
        ss.close();

    }
}

  • 效果图

在这里插入图片描述

3.3 tcp发送和接收数据(服务器有反馈)

  • 客户端
package 网络编程.tcp通信;

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

public class ClientDemo {
    public static void main(String[] args) throws IOException {
//        1.创建客户端的tcp通信
        Socket s = new Socket("10.152.242.223", 12345);

//        2.获取输出流

        OutputStream os = s.getOutputStream();

//        3.写数据
        os.write("hello.world".getBytes());


    //    客户端接收服务端的反馈

        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];

        int len;
        len=is.read(bys);
        System.out.println("服务器的反馈:"+new String(bys,0,len));
        s.close();

    }
}

  • 服务端
package 网络编程.tcp通信;

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

public class ServerDemo {
    public static void main(String[] args) throws IOException {
//        1.服务器端

        ServerSocket ss= new ServerSocket(12345);

//        2.获取输入流

//        使用ss.accept()方法连接此套接字并接收

        Socket s = ss.accept();
//          获取输入流
        InputStream is = s.getInputStream();

        byte[] bys = new byte[1024];
        int len;
        len=is.read(bys);
            String s1 = new String(bys, 0, len);
            System.out.println("接收的数据为"+s1);


        //写反馈给客户端

        OutputStream os = s.getOutputStream();
        os.write("数据已经接收".getBytes());


        s.close();
        ss.close();

    }
}

  • 效果图

在这里插入图片描述

3.4 tcp发送和接收数据(输入来自键盘输入)

  • 客户端
package 网络编程.tcp通信;

import java.io.*;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
//        1.创建客户端的tcp通信
        Socket s = new Socket("10.152.242.223", 12345);

//        2.获取输出流

        OutputStream os = s.getOutputStream();

//        3.写数据

        //数据来源键盘输入
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
        //os.write("hello.world".getBytes());

        String str;
        while((str=br.readLine())!=null){
            //如果键盘输入886,停止发送
            if(str.equals("886")){
                break;
            }else{
                bw.write(str);
                bw.newLine();
                bw.flush();
            }
        }


    //    客户端接收服务端的反馈

        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];

        int len;
        len=is.read(bys);
        System.out.println("服务器的反馈:"+new String(bys,0,len));
        s.close();

    }
}

  • 服务端
package 网络编程.tcp通信;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
//        1.服务器端

        ServerSocket ss= new ServerSocket(12345);

//        2.获取输入流

//        使用ss.accept()方法连接此套接字并接收

        Socket s = ss.accept();
//          获取输入流
        InputStream is = s.getInputStream();

        //byte[] bys = new byte[1024];
        //int len;
        //len=is.read(bys);
        //String s1 = new String(bys, 0, len);
        //System.out.println("接收的数据为"+s1);

        //通过字符流读数据

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String str;
        while((str=br.readLine())!=null){
            System.out.println(str);
        }


        //写反馈给客户端

        OutputStream os = s.getOutputStream();
        os.write("数据已经接收".getBytes());


        s.close();
        ss.close();

    }
}

  • 效果图

在这里插入图片描述

3.5 tcp发送和接收数据(都来自文件)

  • 客户端
package 网络编程.tcp通信;

import java.io.*;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
//        1.创建客户端的tcp通信
        Socket s = new Socket("10.152.242.223", 12345);

//        2.获取输出流

        OutputStream os = s.getOutputStream();

//        3.写数据

        //数据来源键盘输入
        //BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
        //os.write("hello.world".getBytes());

        //数据来源于文件
        BufferedReader br = new BufferedReader(new FileReader("code\\13.txt"));



        String str;
        while((str=br.readLine())!=null){
            //如果键盘输入886,停止发送
            //if(str.equals("886")){
            //    break;
            //}else{
                bw.write(str);
                bw.newLine();
                bw.flush();
            //}
        }


    //    客户端接收服务端的反馈

        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];

        int len;
        len=is.read(bys);
        System.out.println("服务器的反馈:"+new String(bys,0,len));
        s.close();

    }
}

  • 服务端
package 网络编程.tcp通信;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
//        1.服务器端

        ServerSocket ss= new ServerSocket(12345);

//        2.获取输入流

//        使用ss.accept()方法连接此套接字并接收

        Socket s = ss.accept();
//          获取输入流
        InputStream is = s.getInputStream();

        //byte[] bys = new byte[1024];
        //int len;
        //len=is.read(bys);
        //String s1 = new String(bys, 0, len);
        //System.out.println("接收的数据为"+s1);

        //通过字符流读数据

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String str;

        //数据写入文件
        BufferedWriter bw = new BufferedWriter(new FileWriter("code\\14.txt"));
        while((str=br.readLine())!=null){
            //System.out.println(str);
            bw.write(str);
            bw.newLine();
            bw.flush();
        }


        //写反馈给客户端

        OutputStream os = s.getOutputStream();
        os.write("数据已经接收".getBytes());


        s.close();
        ss.close();

    }
}

  • 效果图

在这里插入图片描述

3.6 客户端告知服务端传输完毕的方法

  • 相关方法
方法名说明
void shutdownInput()将此套接字的输入流放置在流的末尾
void shutdownOutput()禁止用此套接字的输出流
  • 客户端
package 网络编程.tcp通信;

import java.io.*;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
//        1.创建客户端的tcp通信
        Socket s = new Socket("10.152.242.223", 12345);

//        2.获取输出流

        OutputStream os = s.getOutputStream();

//        3.写数据

        //数据来源键盘输入
        //BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
        //os.write("hello.world".getBytes());

        //数据来源于文件
        BufferedReader br = new BufferedReader(new FileReader("code\\13.txt"));



        String str;
        while((str=br.readLine())!=null){
            //如果键盘输入886,停止发送
            //if(str.equals("886")){
            //    break;
            //}else{
                bw.write(str);
                bw.newLine();
                bw.flush();
            //}
        }

        //告知服务端传输完毕
        s.shutdownOutput();


    //    客户端接收服务端的反馈

        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];

        int len;
        len=is.read(bys);
        System.out.println("服务器的反馈:"+new String(bys,0,len));
        s.close();

    }
}

  • 服务端
package 网络编程.tcp通信;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerDemo {
    public static void main(String[] args) throws IOException {
//        1.服务器端

        ServerSocket ss= new ServerSocket(12345);

//        2.获取输入流

//        使用ss.accept()方法连接此套接字并接收

        Socket s = ss.accept();
//          获取输入流
        InputStream is = s.getInputStream();

        //byte[] bys = new byte[1024];
        //int len;
        //len=is.read(bys);
        //String s1 = new String(bys, 0, len);
        //System.out.println("接收的数据为"+s1);

        //通过字符流读数据

        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String str;

        //数据写入文件
        BufferedWriter bw = new BufferedWriter(new FileWriter("code\\14.txt"));
        while((str=br.readLine())!=null){
            //System.out.println(str);
            bw.write(str);
            bw.newLine();
            bw.flush();
        }


        //写反馈给客户端

        OutputStream os = s.getOutputStream();
        os.write("数据已经接收".getBytes());


        s.close();
        ss.close();

    }
}

  • 效果图

在这里插入图片描述

3.7 为每个客户端都开启一个线程

  • 客户端
package 网络编程.tcp通信;

import java.io.*;
import java.net.Socket;

public class ClientDemo {
    public static void main(String[] args) throws IOException {
//        1.创建客户端的tcp通信
        Socket s = new Socket("10.152.242.223", 12345);

//        2.获取输出流

        OutputStream os = s.getOutputStream();

//        3.写数据

        //数据来源键盘输入
        //BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
        //os.write("hello.world".getBytes());

        //数据来源于文件
        BufferedReader br = new BufferedReader(new FileReader("code\\13.txt"));



        String str;
        while((str=br.readLine())!=null){
            //如果键盘输入886,停止发送
            //if(str.equals("886")){
            //    break;
            //}else{
                bw.write(str);
                bw.newLine();
                bw.flush();
            //}
        }

        //告知服务端传输完毕
        s.shutdownOutput();


    //    客户端接收服务端的反馈

        InputStream is = s.getInputStream();
        byte[] bys = new byte[1024];

        int len;
        len=is.read(bys);
        System.out.println("服务器的反馈:"+new String(bys,0,len));
        s.close();

    }
}

  • 服务线程类
package 网络编程.tcp通信;

import java.io.*;
import java.net.Socket;

public class ServerThread implements Runnable{

    private Socket s;

    public ServerThread(Socket s) {
        this.s = s;
    }

    @Override
    public void run() {

    //    创建一个字符输入流
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        } catch (IOException e) {
            e.printStackTrace();
        }

        int count=20;
        //输入的文件位置
        File file = new File("code\\12" + count + ".txt");
        //防止文件重名,如果存在,则使文件名+1
        while(file.exists()){
            count++;
            file = new File("code\\12" + count + ".txt");
        }

        //写入文件字符流
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new FileWriter(file));
        } catch (IOException e) {
            e.printStackTrace();
        }

        String str;
        try{
            while((str=br.readLine())!=null){
                bw.write(str);
                bw.newLine();
                bw.flush();
            }

            OutputStream os = s.getOutputStream();
            os.write("数据已经接收".getBytes());
            s.close();
        }catch (IOException e){
            e.printStackTrace();
        }





    }




}

  • 服务端
package 网络编程.tcp通信;

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

public class ServerDemo2 {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(12345);

        while(true){
        //    监听是否有多个客户端,返回多个Socket对象

            Socket s = ss.accept();

        //    每个对象新建一个线程

            new Thread(new ServerThread(s)).start();
        }
    }
}

  • 效果图

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值