java网络编程基础之TCP网络编程

目录

Socket

基本介绍:

  1. 套接字(Socket)开发网络应用程序被广泛采用,以至于成为事实上的标准
  2. 通信的两端都要有Socket,是两台机器间通信的端点
  3. 网络通信其实就是Socket间的通信
  4. Socket允许将网络连接当成一个流,数据在两个Socket间通过IO传输
  5. 一般主动发起通信的应用程序属于客户端,等待通信请求的为服务端
  6. 支持TCP协议和UDP协议

示意图:

alt 需要通讯时:(读写数据)

  1. socket.getOutputStresm()
  2. socket.getInputStream()

TCP网络通信编程

基本介绍:

  1. 基于客户端————服务端的网络通信
  2. 底层使用的是TCP/IP协议
  3. 应用场景举例:客户端发送数据,服务端接收数据
  4. 基于Socket的TCP编程 alt

示例(基于TCP协议实现服务端和客户端的网络通信)

基本思路:

-客户端:获得服务端的InetAddress对象(ip)和服务端所监听的端口号,将数据传入数据通道,设置传出结束标志,准备接收服务端返回的信息 -服务端:设置端口号(此端口号不能被其他程序占用),监听此端口号,如果有客户端向此端口的数据通道发送数据,进行接收,打印在命令行,然后设置传入结束标志,并回复消息

(字节流方式)服务端代码实现

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

/**
 * 服务端
 */
public class SocketTCP01Server {
    public static void main(String[] args) throws IOException {
        //在9999端口监听
        //注意:确保9999端口号没有被其他程序监听
        // serverSocket可以多次accept,等待多个服务端的连接
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端正在监听9999号端口,等待客户端发送数据...");
        //当没有服务端连接9999端口时,程序会阻塞,等待连接
        //当有服务端连接9999端口时,程序会继续,返回Socket对象
        Socket socket = serverSocket.accept();
        //通过输入流获取socket接收到的数据
        InputStream inputStream = socket.getInputStream();
        //读取输入流中的数据
        byte[] bytes=new byte[1024];
        int bytesLength=0;
        while ((bytesLength=inputStream.read(bytes))!=-1){
            System.out.print(new String(bytes,0,bytesLength));
        }
        System.out.println();
        //设置输入结束标志
        socket.shutdownInput();
        //通过输出流向数据通道传输数据
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello ,client".getBytes(StandardCharsets.UTF_8));
        //关闭输出流
        outputStream.close();
        //关闭输入流
        inputStream.close();
        //关闭socket
        socket.close();
        //关闭serverSocket
        serverSocket.close();
        System.out.println("服务端退出");
    }
}

(字节流方式)客户端代码实现

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class SocketTCP01Client {
    public static void main(String[] args) throws IOException {
        //获取服务端的ip和服务的端口号(这里服务端是本机,如果远程服务器,可以输入远程服务器的ip地,例如"192.168.56.1")
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        //通过输出流向服务端传输数据
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("hello,sever".getBytes(StandardCharsets.UTF_8));
        //设置输出流结束标志
        socket.shutdownOutput();
        //通过输入流接收服务端传过来的数据
        InputStream inputStream = socket.getInputStream();
        //打印数据
        byte[] bytes=new byte[1024];
        int byteLength=0;
        while ((byteLength=inputStream.read(bytes))!=-1){
            System.out.print(new String(bytes,0,byteLength));
        }
        System.out.println();
        //关闭输入流
        inputStream.close();
        //关闭输出流
        outputStream.close();
        //关闭socket
        socket.close();
        System.out.println("客户端退出");
    }
}

开启服务端后:

服务端正在监听9999号端口,等待客户端发送数据...

开启客户端后: 客户端:

hello ,client
客户端退出

服务端:

服务端正在监听9999号端口,等待客户端发送数据...
hello,sever
服务端退出

(字符流方式)服务端代码实现:


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

public class SocketTCP03Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);
        Socket socket = serverSocket.accept();
        System.out.println("服务端正在监听9999号端口,等待客户端发送数据...");
        //将字节流转换成字符流用处理流接收
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String information=bufferedReader.readLine();
        System.out.println(information);
        //将字节流转换成字符流用处理流接收
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bufferedWriter.write("hello,client");
        //设置结束标志(这里用newLine方法作为结束方式,那么另一端必须用readLine进行接收)
        bufferedWriter.newLine();
        //刷新(必须刷新,否则无法写入数据通道)
        bufferedWriter.flush();
        bufferedWriter.close();
        bufferedReader.close();
        socket.close();
        serverSocket.close();
        System.out.println("服务端推出");


    }
}

(字符流方式)客户端代码实现:


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

public class SocketTCP03Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        //将字节流转换成字符流用处理流接收
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bufferedWriter.write("hello,server");
        //设置结束标志(这里用newLine方法作为结束方式,那么另一端必须用readLine进行接收)
        bufferedWriter.newLine();
        //刷新(必须刷新,否则无法写入数据通道)
        bufferedWriter.flush();
        //将字节流转换成字符流用处理流接收
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String information=bufferedReader.readLine();
        System.out.println(information);
        bufferedReader.close();
        bufferedWriter.close();
        socket.close();
        System.out.println(" 客户端退出");
    }
}

开启服务端后:

服务端正在监听9999号端口,等待客户端发送数据...

开启客户端后: 客户端:

hello ,client
客户端退出

服务端:

服务端正在监听9999号端口,等待客户端发送数据...
hello,sever
服务端退出

模拟在服务端下载文件

基本思路:

  • 客户端向服务端发送文件地址
  • 服务端接收文件地址,并在磁盘中读取文件到输入流中
  • 服务端将输入中的数据发送给客户端
  • 客户端接收数据放入输出流中,并存储到指定的路径
  • 客户端向服务端发送下载成功,并给出提示信息后退出
  • 服务端接收到客户端发来的信息,打印输出后退出

服务端代码实现:



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

public class TCPFileDownloadServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端已启动...");
        Socket socket = serverSocket.accept();
        //获取文件下载路径及文件名
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        String src = bufferedReader.readLine();
        //读入文件到输入流
        InputStream fileInputStream = new FileInputStream(src);
        //准备向客户端发送文件数据
        OutputStream outputStream = socket.getOutputStream();
        byte[] bytes = fileInputStream.readAllBytes();
        //向数据通道写入文件数据
        outputStream.write(bytes);
        //结束标志
        socket.shutdownOutput();
        /*****************************************/
        //准备接收客户端返回的数据
        BufferedReader bufferedReader1 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String success = bufferedReader1.readLine();
        //打印输出
        System.out.println(success);
        /**********************************************/
        //关闭各种流及socket和serverSocket
        bufferedReader1.close();
        outputStream.close();
        fileInputStream.close();
        socket.close();
        serverSocket.close();
        System.out.println("服务端退出");

    }
}

客户端代码实现:


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

public class TCPFileDownloadClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        //准备向服务端发送文件路径及文件名
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bufferedWriter.write("src\\cert.png");
        //结束标志
        bufferedWriter.newLine();
        //刷新
        bufferedWriter.flush();
        /***************************************************/
        //准备下载文件
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = inputStream.readAllBytes();
        //设置文件下载的路径
        String fileDownloadPath="src\\download\\";
        File file = new File(fileDownloadPath);
        boolean mkdirs = file.mkdirs();
        //将文件数据写入到cert.png中
        FileOutputStream fileOutputStream = new FileOutputStream(fileDownloadPath+"cert.png");
        fileOutputStream.write(bytes);
        //结束标志
        socket.shutdownInput();
        /***********************************************************/
        //准备向服务器回应下载成功的消息
        BufferedWriter bufferedWriter1 = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bufferedWriter1.write("下载成功");
        bufferedWriter1.newLine();
        bufferedWriter1.flush();
        //客户端提升下载成功
        System.out.println("下载成功");
        /*************************************************************/
        //关闭各种流及socket
        bufferedWriter1.close();
        fileOutputStream.close();
        inputStream.close();
        bufferedWriter.close();
        socket.close();
        System.out.println("客户端退出");

    }
}

输出:略。

netstat 指令

  • netstat指令
  1. netstat -an 可以查看当前主机的网络情况,包括端口监听情况和网络连接情况
  2. netstat -an | more 可以分页显示
  3. 在dos 控制台执行
  • 说明:
  1. Listening表示某个端口在监听
  2. 如果有一个外部程序(客户端)连接到该端口,就会显示一条连接消息
  3. Ctrl+c退出指令
全部评论

相关推荐

牛客868257804号:九个中铁八个中建
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务