Java NetWork笔记+作业

基本原理

 

 

UDP编程

传输原理

 

发送端步骤

  • 创建socket对象(DatagramSocket)

  • 把要发送的数据封装成数据报包

  • 通过send(数据报包)方法把数据报包发送出去

  • close释放资源

接收端步骤

  • 创建接收端的socket对象(DatagramSocket)

  • 创建用于接收的数据报包

  • 通过receive(数据报包)方法进行接收

  • 解析数据报包, 把数据从包里取出来

  • close释放资源

DatagramSocket

此类表示用来 发送接收 数据报包的套接字

构造方法

DatagramSocket(int port) 创建数据报套接字并将其绑定到本地主机上的指定端口。

成员方法

voidreceive(DatagramPacket p) 从此套接字接收数据报包。
voidsend(DatagramPacket p) 从此套接字发送数据报包。

DatagramPacket

此类表示数据报包

构造方法

用于发送的

 DatagramPacket(byte[] buf,  int offset, int length, InetAddress address, int port)        构造数据报包,用来将长度为 length 偏移量为 offset  的包发送到指定主机上的指定端口号。

用于接收的

 DatagramPacket(byte[] buf, int offset, int length) 
           构造 DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量。

成员方法

byte[]getData() 返回数据缓冲区。
intgetLength() 返回将要发送或接收到的数据的长度。
intgetOffset() 返回将要发送或接收到的数据的偏移量。

案例

v1 发送端发送消息,接收端接收并打印

 
package _22network.com.cskaoyan.udp.v1;
 ​
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 ​
 /**
  * @description: 接收端
  * @author: 景天
  * @date: 2022/6/30 16:27
  **/
 ​
 public class Receiver {
     public static void main(String[] args) throws IOException {
         // - 创建接收端的socket对象(DatagramSocket)
         DatagramSocket datagramSocket = new DatagramSocket(9999);
         //- 创建用于接收的数据报包
         // DatagramPacket(byte[] buf, int offset, int length)
         // 构造 DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量。
         byte[] bytes = new byte[1024];
         DatagramPacket receivePacket = new DatagramPacket(bytes, 0, bytes.length);
 ​
         //- 通过receive(数据报包)方法进行接收
         System.out.println("receive before");
         datagramSocket.receive(receivePacket);
         System.out.println("receive after");
 ​
         //- 解析数据报包, 把数据从包里取出来
         byte[] data = receivePacket.getData();
         int offset = receivePacket.getOffset();
         int length = receivePacket.getLength();
         String s = new String(data, offset, length);
         System.out.println("接收到了来自"+receivePacket.getSocketAddress()+
                "的消息: " +s);
         //- close释放资源
         datagramSocket.close();
     }
 }
 ​
 ​
 package _22network.com.cskaoyan.udp.v1;
 ​
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
 ​
 /**
  * @description: 发送端
  * @author: 景天
  * @date: 2022/6/30 16:16
  **/
 ​
 /*
 v1 发送端发送消息,接收端接收并打印
  */
 public class Sender {
     public static void main(String[] args) throws IOException {
         // - 创建socket对象(DatagramSocket)
         DatagramSocket datagramSocket = new DatagramSocket(8888);
         //- 把要发送的数据封装成数据报包
         String s = "hello udp";
         // DatagramPacket(byte[] buf,  int offset, int length, InetAddress address, int port)
         // 构造数据报包,用来将长度为 length 偏移量为 offset  的包发送到指定主机上的指定端口号。
         byte[] bytes = s.getBytes();
         InetAddress targetIp = InetAddress.getByName("127.0.0.1");
         int port = 9999;
         DatagramPacket sendPacket =
                 new DatagramPacket(bytes, 0, bytes.length, targetIp, port);
 ​
         //- 通过send(数据报包)方法把数据报包发送出去
         datagramSocket.send(sendPacket);
         //- close释放资源
         datagramSocket.close();
     }
 }
我的

package com._24_network._01_udp.ver1;

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

/**
 * 发送端
 *
 * @author zxcsjf
 * @since 2022/06/30 19:18
 */
public class Sender {
    public static void main(String[] args) throws IOException {

        // 1.创建发送端的socket对象,port绑定本机端口
        DatagramSocket datagramSocket = new DatagramSocket(8888);

        // 2.把要发送的数据变成字节数组
        String s = "lalalalal~~~~";
        byte[] bytes = s.getBytes();

        // 3.得到目标ip
        InetAddress targetIP = InetAddress.getByName("192.168.13.255");
        // InetAddress localHost = InetAddress.getLocalHost();

        // 4.目标端口号
        int port = 9999;

        // 6.封装成数据报包
        DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length, targetIP, port);

        // 7.通过send(包) 发送出去
        datagramSocket.send(datagramPacket);

        // 8.close
        datagramSocket.close();
    }
}

——————————————————————————————————————————————————————————————————————————————
package com._24_network._01_udp.ver1;

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

/**
 * @author zxcsjf
 * @since 2022/06/30 19:29
 */
public class Receiver {
    public static void main(String[] args) throws IOException {
        // 1.创建接收端的socket对象
        DatagramSocket datagramSocket = new DatagramSocket(9999);

        // 2.创建用于存放数据的字符数组
        byte[] bytes = new byte[1024];

        // 3.创建用于接收数据的数据报包
        DatagramPacket receivePacket = new DatagramPacket(bytes, 0, bytes.length);

        // 4.调用socket的receive方法进行接收
        datagramSocket.receive(receivePacket);

        // 5.解析数据报包,把数据从包中取出,放入字符串
        byte[] data = receivePacket.getData();
        int offSet = receivePacket.getOffset();
        int length = receivePacket.getLength();
        String s = new String(data, offSet, length);
        System.out.println("接受到了来自" + receivePacket.getSocketAddress() + "的消息:" + s);

        // 6.释放资源,
        datagramSocket.close();

    }
}
 

v2 使用工具类优化v1

 
package _22network.com.cskaoyan.udp.v1;
 ​
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 ​
 /**
  * @description: 接收端
  * @author: 景天
  * @date: 2022/6/30 16:27
  **/
 ​
 public class Receiver {
     public static void main(String[] args) throws IOException {
         // - 创建接收端的socket对象(DatagramSocket)
         DatagramSocket datagramSocket = new DatagramSocket(9999);
         //- 创建用于接收的数据报包
         // DatagramPacket(byte[] buf, int offset, int length)
         // 构造 DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量。
         byte[] bytes = new byte[1024];
         DatagramPacket receivePacket = new DatagramPacket(bytes, 0, bytes.length);
 ​
         //- 通过receive(数据报包)方法进行接收
         System.out.println("receive before");
         datagramSocket.receive(receivePacket);
         System.out.println("receive after");
 ​
         //- 解析数据报包, 把数据从包里取出来
         byte[] data = receivePacket.getData();
         int offset = receivePacket.getOffset();
         int length = receivePacket.getLength();
         String s = new String(data, offset, length);
         System.out.println("接收到了来自"+receivePacket.getSocketAddress()+
                "的消息: " +s);
         //- close释放资源
         datagramSocket.close();
     }
 }
 package _22network.com.cskaoyan.udp.v2;
 ​
 import utils.NetWorkUtils;
 ​
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 ​
 /**
  * @description: 接收端
  * @author: 景天
  * @date: 2022/6/30 16:48
  **/
 ​
 public class Receiver {
     public static void main(String[] args) throws IOException {
         // 创建接收端的socket对象
         DatagramSocket datagramSocket = new DatagramSocket(9999);
         // 创建用于接收的数据报包
         DatagramPacket receivePacket = NetWorkUtils.getReceivePacket();
         // receive
         datagramSocket.receive(receivePacket);
         // 解析
         String msg = NetWorkUtils.parse(receivePacket);
         System.out.println(receivePacket.getSocketAddress()+":  " + msg);
         // close
         datagramSocket.close();
     }
 }
————————————————————————————————————————————————————————————————————————————————————————
package utils;

import java.io.Reader;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * @description:
 * @author: 景天
 * @date: 2022/6/30 16:38
 **/

public class NetWorkUtils {
    // 获取发送的数据报包
    public static DatagramPacket getSendPacket(String msg,String ip,int port)
            throws UnknownHostException {
        // 把数据封装成包
        byte[] bytes = msg.getBytes();
        InetAddress targetIp = InetAddress.getByName(ip);
        DatagramPacket sendPacket =
                new DatagramPacket(bytes, 0,
                        bytes.length, targetIp, port);

        // 最终要返回装满了数据的包
        return sendPacket;
    }

    // 获取接收的数据报包
    public static DatagramPacket getReceivePacket() {
        // 构建用于接收的包
        byte[] bytes = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(bytes, 0,
                bytes.length);
        return receivePacket;
    }

    // 解析数据的方法
    public static String parse(DatagramPacket packet) {
        // 解析数据
        byte[] data = packet.getData();
        int offset = packet.getOffset();
        int length = packet.getLength();
        String s = new String(data, offset, length);
        return s;
    }
}
 ​

v3 发送端接收端相互发送

 package _22network.com.cskaoyan.udp.v3;
 ​
 import utils.NetWorkUtils;
 ​
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.util.Scanner;
 ​
 /**
  * @description: 接收端
  * @author: 景天
  * @date: 2022/6/30 17:17
  **/
 ​
 public class Receiver {
     public static void main(String[] args) throws IOException {
         // 创建接收端的socket对象
         DatagramSocket datagramSocket = new DatagramSocket(9999);
         // 创建scanner对象
         Scanner scanner = new Scanner(System.in);
         // while循环
         while (true) {
             // 接收逻辑
             // 创建用于接收的数据报包
             DatagramPacket receivePacket = NetWorkUtils.getReceivePacket();
             // receive接收
             datagramSocket.receive(receivePacket);
             // 解析
             String msg = NetWorkUtils.parse(receivePacket);
             System.out.println(msg);
 ​
             // 发送逻辑
             // 键盘接收数据
             String s = scanner.nextLine();
             // 把数据封装成数据报包
             DatagramPacket sendPacket =
                     NetWorkUtils.getSendPacket(s, "127.0.0.1", 8888);
             // send发送
             datagramSocket.send(sendPacket);
 ​
         }
     }
 }
 ​
 ​
 package _22network.com.cskaoyan.udp.v3;
 ​
 import utils.NetWorkUtils;
 ​
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.util.Scanner;
 ​
 /**
  * @description: 发送端
  * @author: 景天
  * @date: 2022/6/30 17:12
  **/
 ​
 /*
 发送端接收端相互发送
  */
 public class Sender {
     public static void main(String[] args) throws IOException {
         // 创建发送端的socket对象
         DatagramSocket datagramSocket = new DatagramSocket(8888);
         // 创建Scanner对象
         Scanner scanner = new Scanner(System.in);
         // while循环
         while (true) {
             // 发送逻辑
             // 键盘接收数据
             String s = scanner.nextLine();
             // 把数据封装成数据报包
             DatagramPacket sendPacket =
                     NetWorkUtils.getSendPacket(s, "127.0.0.1", 9999);
             // send发送
             datagramSocket.send(sendPacket);
 ​
             // 接收逻辑
             // 创建用于接收的数据报包
             DatagramPacket receivePacket = NetWorkUtils.getReceivePacket();
             // receive方法接收
             datagramSocket.receive(receivePacket);
             // 解析
             String msg = NetWorkUtils.parse(receivePacket);
             System.out.println(msg);
 ​
         }
     }
 }
 ​

v4 使用多线程优化v3

思路:

 

OnePerson

AnotherPerson

定义2个任务

发送任务 只发送消息SendTask

  • 定义一个成员变量 DatagramSocket

  • ip

  • port

接收任务 只接收消息ReceiveTask

  • 定义一个成员变量 DatagramSocket

 package _22network.com.cskaoyan.udp.v4;
 ​
 import java.io.IOException;
 import java.net.DatagramSocket;
 ​
 /**
  * @description:
  * @author: 景天
  * @date: 2022/6/30 17:42
  **/
 ​
 public class AnotherPerson {
     public static void main(String[] args) throws IOException {
         // 创建socket对象
         DatagramSocket datagramSocket = new DatagramSocket(9999);
         // 创建接收,发送任务
         // 运行在线程中
         new Thread(new SendTask(datagramSocket,"127.0.0.1",8888)).start();
         new Thread(new ReceiveTask(datagramSocket)).start();
     }
 }
 ​
 ​
 ​
 ​
 package _22network.com.cskaoyan.udp.v4;
 ​
 import java.io.IOException;
 import java.net.DatagramSocket;
 ​
 /**
  * @description:
  * @author: 景天
  * @date: 2022/6/30 17:42
  **/
 ​
 public class OnePerson {
     public static void main(String[] args) throws IOException {
         // 创建socket对象
         DatagramSocket datagramSocket = new DatagramSocket(8888);
         // 创建接收,发送任务
         // 运行在线程中
         new Thread(new SendTask(datagramSocket,"127.0.0.1",9999)).start();
         new Thread(new ReceiveTask(datagramSocket)).start();
     }
 }
 ​
 ​
 ​
 ​
 package _22network.com.cskaoyan.udp.v4;
 ​
 import utils.NetWorkUtils;
 ​
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 ​
 /**
  * @description: 接收消息的任务
  * @author: 景天
  * @date: 2022/6/30 17:39
  **/
 ​
 public class ReceiveTask implements Runnable{
     // 定义一个成员变量 DatagramSocket
     DatagramSocket datagramSocket;
 ​
     public ReceiveTask(DatagramSocket datagramSocket) {
         this.datagramSocket = datagramSocket;
     }
 ​
     @Override
     public void run() {
         // 只接收消息
         while (true) {
             // 创建用于接收的数据报包
             DatagramPacket receivePacket = NetWorkUtils.getReceivePacket();
             // receive方法接收数据
             try {
                 datagramSocket.receive(receivePacket);
                 // parse
                 String msg = NetWorkUtils.parse(receivePacket);
                 // 打印
                 System.out.println("接收到了来自" +
                         receivePacket.getSocketAddress() +
                         "的消息: " + msg);
 ​
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }
 }
 ​
 ​
 package _22network.com.cskaoyan.udp.v4;
 ​
 import utils.NetWorkUtils;
 ​
 import java.io.IOException;
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.UnknownHostException;
 import java.util.Scanner;
 ​
 /**
  * @description: 发送任务
  * @author: 景天
  * @date: 2022/6/30 17:35
  **/
 ​
 /*
 - 定义一个成员变量 DatagramSocket
 - ip
 - port
  */
 public class SendTask implements Runnable{
     // 定义成员变量
     DatagramSocket datagramSocket;
     String ip;
     int port;
 ​
     public SendTask(DatagramSocket datagramSocket, String ip, int port) {
         this.datagramSocket = datagramSocket;
         this.ip = ip;
         this.port = port;
     }
 ​
     @Override
     public void run() {
         // 创建Scanner对象
         Scanner scanner = new Scanner(System.in);
         // 只发送消息
         while (true) {
             // 键盘接收数据
             String msg = scanner.nextLine();
             // 把数据封装成数据报包
             try {
                 DatagramPacket sendPacket =
                         NetWorkUtils.getSendPacket(msg, ip, port);
                 // send
                 datagramSocket.send(sendPacket);
             } catch (UnknownHostException e) {
                 e.printStackTrace();
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }
 }
 ​

TCP编程

传输原理

 

 

客户端步骤(Client)

  • 创建客户端socket对象

  • 从socket对象中获取输入输出流

  • 利用输入输出流进行读写操作

  • close释放资源

服务端步骤(Server)

  • 创建服务端socket对象(ServerSocket)

  • 利用accept方法建立连接,得到socket对象

  • 从socket对象中获取输入输出流

  • 利用输入输出流进行读写操作

  • close释放资源

Socket

此类实现客户端套接字

构造方法

Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号

成员方法

InputStreamgetInputStream() 返回此套接字的输入流。
OutputStreamgetOutputStream() 返回此套接字的输出流。

Socket半关闭

voidshutdownOutput() 禁用此套接字的输出流。

ServerSocket

此类实现服务器套接字

构造方法

ServerSocket(int port) 创建绑定到特定端口的服务器套接字。

成员方法

Socketaccept() 侦听并接受到此套接字的连接。

案例

v1 客户端发送消息,服务端接收并打印

 package _22network.com.cskaoyan.tcp.v1;
 ​
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.Socket;
 ​
 /**
  * @description: 客户端
  * @author: 景天
  * @date: 2022/7/1 9:46
  **/
 ​
 /*
 客户端发送消息,服务端接收并打印
  */
 public class Client {
     public static void main(String[] args) throws IOException {
         // 创建客户端socket对象
         Socket socket = new Socket("127.0.0.1", 9999);
 ​
         // 获取输出流
         OutputStream out = socket.getOutputStream();
 ​
         // write数据
         out.write("hello tcp".getBytes());
 ​
         // close
         out.close();
     }
 }
 ​
 ​
 ​
 package _22network.com.cskaoyan.tcp.v1;
 ​
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.ServerSocket;
 import java.net.Socket;
 ​
 /**
  * @description: 服务端
  * @author: 景天
  * @date: 2022/7/1 9:49
  **/
 ​
 public class Server {
     public static void main(String[] args) throws IOException {
         //  创建服务端socket对象
         ServerSocket serverSocket = new ServerSocket(9999);
         // 建立连接  accept方法  --> socket对象
         System.out.println("accept before");
         Socket socket = serverSocket.accept();
         System.out.println("accept after");
 ​
         // 从socket对象中获取输入流
         InputStream in = socket.getInputStream();
         // read读取数据
         byte[] bytes = new byte[1024];
         int readCount = in.read(bytes);
         String s = new String(bytes, 0, readCount);
         System.out.println(socket.getInetAddress() +"--"+socket.getPort()+ "--" + s);
         // close
         socket.close();
         serverSocket.close();
     }
 }
 ​

v2 多个客户端发送,服务端接收(多线程处理)

 
package _22network.com.cskaoyan.tcp.v2;
 ​
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 ​
 /**
  * @description: 服务端
  * @author: 景天
  * @date: 2022/7/1 10:06
  **/
 ​
 public class Server {
     public static void main(String[] args) throws IOException {
         // 创建服务端socket对象
         ServerSocket serverSocket = new ServerSocket(8888);
         // 创建线程池
         ExecutorService pool = Executors.newFixedThreadPool(2);
         // 循环
         while (true) {
             // 建立连接 得到Socket对象
             Socket socket = serverSocket.accept();
             //new Thread(new ConnectTask(socket)).start();
             // 使用线程池
             pool.submit(new ConnectTask(socket));
 ​
         }
     }
 }
 ​
 class ConnectTask implements Runnable{
 ​
     // 定义成员变量
     Socket socket;
 ​
     public ConnectTask(Socket socket) {
         this.socket = socket;
     }
 ​
     @Override
     public void run() {
         while (true) {
             // 读取来自客户端的数据
             try {
                 // 获取输入流
                 InputStream in = socket.getInputStream();
                 // read读一下
                 byte[] bytes = new byte[1024];
                 int readCount = in.read(bytes);
                 String s = new String(bytes, 0, readCount);
                 System.out.println(socket.getInetAddress() + ":" + socket.getPort() +
                         "--" + Thread.currentThread().getName() + s);
             } catch (IOException e) {
                 e.printStackTrace();
             }
         }
     }
 }
 ​
 ​
 package _22network.com.cskaoyan.tcp.v2;
 ​
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.Socket;
 import java.util.Scanner;
 ​
 /**
  * @description:
  * @author: 景天
  * @date: 2022/7/1 9:58
  **/
 ​
 /*
  多个客户端发送,服务端接收(多线程处理)
  */
 public class Client {
     public static void main(String[] args) throws IOException {
         // 创建客户端socket对象
         Socket socket = new Socket("127.0.0.1", 8888);
         // 创建Scanner对象
         Scanner scanner = new Scanner(System.in);
         // while循环
         while (true) {
             // 键盘接收数据
             String s = scanner.nextLine();
             // 从socket中获取输出流
             OutputStream out = socket.getOutputStream();
             out.write(s.getBytes());
 ​
         }
     }
 }
 ​

v3 客户端发送对象(序列化),服务端接收

 
package _22network.com.cskaoyan.tcp.v3;
 ​
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.ObjectInputStream;
 import java.net.ServerSocket;
 import java.net.Socket;
 ​
 /**
  * @description:
  * @author: 景天
  * @date: 2022/7/1 10:24
  **/
 ​
 public class Server {
     public static void main(String[] args) throws IOException, ClassNotFoundException {
         // 创建服务端Socket对象
         ServerSocket serverSocket = new ServerSocket(12306);
         // 跟客户端建立连接
         Socket socket = serverSocket.accept();
         // 得到socket对象
 ​
         // 从socket中获取输入流
         InputStream in = socket.getInputStream();
 ​
         // 利用反序列流进行包装
         ObjectInputStream objectInputStream = new ObjectInputStream(in);
 ​
         // readObject读取对象
         Object o = objectInputStream.readObject();
 ​
         // 打印
         System.out.println(o);
 ​
         // close
         socket.close();
         serverSocket.close();
     }
 }
 ​
 ​
 ​
 ​
 package _22network.com.cskaoyan.tcp.v3;
 ​
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import java.net.Socket;
 ​
 /**
  * @description:
  * @author: 景天
  * @date: 2022/7/1 10:20
  **/
 ​
 /*
 v3 客户端发送对象(序列化),服务端接收
  */
 public class Client {
     public static void main(String[] args) throws IOException {
         // 创建客户端Socket对象
         Socket socket = new Socket("127.0.0.1", 12306);
         // 创建学生对象
         Student student = new Student("zs", 20);
         // 从Socket中获取输出流
         OutputStream out = socket.getOutputStream();
         // 利用序列化流进行包装
         ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
 ​
         // writeObject(学生对象)
         objectOutputStream.writeObject(student);
 ​
         // close
         socket.close();
     }
 }

v4 客户端上传文件到服务端

思路:

package _22network.com.cskaoyan.tcp.v4;
 ​
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.Socket;
 ​
 /**
  * @description:
  * @author: 景天
  * @date: 2022/7/1 10:59
  **/
 ​
 /*
 客户端上传文件到服务端
  */
 public class Client {
     public static void main(String[] args) throws IOException {
         // 创建客户端的socket对象
         Socket socket = new Socket("127.0.0.1", 11111);
         // 创建自己的输入流对象
         FileInputStream in = new FileInputStream("D:\\b.txt");
         // 从socket中获取输出流
         OutputStream out = socket.getOutputStream();
         // 边读边写
         int readCount;
         byte[] bytes = new byte[1024];
         while ((readCount = in.read(bytes)) != -1) {
             out.write(bytes,0,readCount);
         }
 ​
         // 循环结束意味着文件已经上传到服务器
         System.out.println("客户端已经上传完毕");
         // 禁用此套接字的输出流 shutdownOutput()
         socket.shutdownOutput();
 ​
         // 接收来自服务端的反馈消息
         // 从socket中获取输入流
         InputStream inputStream = socket.getInputStream();
         // 读取数据
         byte[] bytes1 = new byte[1024];
         System.out.println("read before");
         int readCount2 = inputStream.read(bytes1);
         System.out.println("read after");
 ​
         System.out.println(new String(bytes1,0,readCount2));
 ​
         // close
         in.close();
         socket.close();
     }
 }
 ​
 ​
 ​
 package _22network.com.cskaoyan.tcp.v4;
 ​
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.ServerSocket;
 import java.net.Socket;
 ​
 /**
  * @description: 服务端
  * @author: 景天
  * @date: 2022/7/1 11:03
  **/
 ​
 public class Server {
     public static void main(String[] args) throws IOException {
         // 创建服务端socket对象
         ServerSocket serverSocket = new ServerSocket(11111);
         // 创建自己的输出流对象
         FileOutputStream out = new FileOutputStream("copy_b.txt");
         // accept建立连接 得到socket对象
         Socket socket = serverSocket.accept();
         // 从socket获取输入流
         InputStream in = socket.getInputStream();
         // 边读边写
         int readCount;
         byte[] bytes = new byte[1024];
         while ((readCount = in.read(bytes)) != -1) {
             out.write(bytes,0,readCount);
         }
         System.out.println("end while");
         // 保存成功
         // 给客户端一个反馈消息
         // 从socket中获取输出流
         OutputStream outputStream = socket.getOutputStream();
         // write
         outputStream.write("文件上传成功!".getBytes());
         // close
         out.close();
         socket.close();
         serverSocket.close();
     }
 }
 ​

异常

java.net.ConnectException: Connection refused: connect 先启动了Client

java.net.BindException: Address already in use: JVM_Bind port重复了

作业:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值