41. java网络编程基础--TCP

本文介绍了Java网络编程的基础知识,包括InetAddress类的使用,以及基于Socket的TCP网络编程原理。客户端通过Socket创建连接,发送数据;服务器端通过ServerSocket监听并接受连接,进行数据交互。示例代码展示了客户端发送信息和服务端接收并反馈的过程,以及客户端发送图片服务端接收并保存的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java网络编程基础

回顾计算机网络的相关知识

通信需要IP地址和端口号,InetAddress类主要用来表示IP地址。
在这里插入图片描述
在这里插入图片描述
可通过域名或者直接写入Ip地址的方式获得对应的ip。
如果想获取本地服务器的相关数据,ip设置为127.0.0.1,对应着localhost。

    @Test
    public void test() {
        try {
            InetAddress inetAddress = InetAddress.getByName("182.61.200.6");
            System.out.println(inetAddress);
            InetAddress byName = InetAddress.getByName("www.baidu.com");
            System.out.println(byName);
            InetAddress byName1 = InetAddress.getByName("127.0.0.1");
            System.out.println(byName1);

            InetAddress localHost = InetAddress.getLocalHost();
            System.out.println(localHost);

            String hostName = byName.getHostName();
            System.out.println(hostName); //得到ip对象对应的域名
            String hostAddress = byName.getHostAddress();
            System.out.println(hostAddress);//得到ip对象对应的ip地址
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

在这里插入图片描述


基于Socket的TCP网络编程

在这里插入图片描述

客户端Socket的工作过程包含以下四个基本的步骤:

  1. 创建 Socket: 根据指定服务端的 IP 地址或端口号构造Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。
  2. 打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用getOutputStream()方法获得输出流,进行数据传输
  3. 按照一定的协议对 Socket 进行读/写操作: 通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。
  4. 关闭 Socket: 断开客户端到服务器的连接,释放线路

在这里插入图片描述

服务器程序的工作过程包含以下四个基本的步骤:

  1. 调用 ServerSocket(int port) : 创建一个服务器端套接字,并绑定到指定端口上。用于监听客户端的请求。
  2. 调用 accept(): 监听连接请求,如果客户端请求连接,则接受连接,返回通信套接字对象。
  3. 调用 该Socket类对象的 getOutputStream() 和 getInputStream (): 获取输出流和输入流,开始网络数据的发送和接收。
  4. 关闭ServerSocket和Socket对象: 客户端访问结束,关闭通信套接字。

在这里插入图片描述

package com.senior.internetsocket;

import org.junit.Test;

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

/**
 * @author eden
 * @Description  客户端发送信息给服务端,服务端将其显示在控制台上。
 * @create projectTest-com.senior.internetsocket:2021-05-14-10:52
 * @since
 */
public class TCPTest {

    //客户端
    @Test
    public void client()  {
        Socket socket = null;
        OutputStream outputStream = null;
        try {
            //客户端创建一个socket对象
            InetAddress inetAddress = InetAddress.getLocalHost();
//            InetAddress inetAddress = InetAddress.getByName("127.0.0.1");
            socket = new Socket(inetAddress,8899);
            //创建输出流输出信息
            outputStream = socket.getOutputStream();
            outputStream.write("首次建立通信".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            if(outputStream!=null)
            {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket!=null)
            {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //服务端
    @Test
    public void server(){

        ServerSocket serverSocket = null;
        Socket accept = null;
        InputStream inputStream = null;
        ByteArrayOutputStream arrayOutputStream = null;
        try {
            serverSocket = new ServerSocket(8899);

            accept = serverSocket.accept();

            inputStream = accept.getInputStream();
//由于汉字占3个字节,当byte数组容量设置较小时,可能会出现乱码,因此不建议这样写
//        byte[] bytes = new byte[2];
//        int len;
//        while((len = inputStream.read(bytes))!=-1)
//        {
//            String s = new String(bytes,0,len);
//            System.out.print(s);
//        }
            arrayOutputStream = new ByteArrayOutputStream();
            byte[] bytes = new byte[5];
            int len;
            while((len = inputStream.read(bytes))!=-1)
            {
                //ByteArrayOutputStream会把所有的字节依次放入到一个string中,
                //这样就不会因为拆包而导致乱码
                arrayOutputStream.write(bytes,0,len);
            }
            System.out.print(arrayOutputStream.toString());
            System.out.println();
            System.out.println("收到来自"+accept.getInetAddress().getHostName()+"的信息");//可查看客户端是谁发过来的
            System.out.println("其对应的IP地址:"+accept.getInetAddress().getHostAddress());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(arrayOutputStream!=null){arrayOutputStream.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(inputStream!=null){inputStream.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(accept!=null){accept.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(serverSocket!=null){serverSocket.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

package com.senior.internetsocket;

import org.junit.Test;

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

/**
 * @author eden
 * @Description  客户端发送图片给服务端,服务端接收将其保存下来,并给客户端一个反馈。
 * @create projectTest-com.senior.internetsocket:2021-05-14-10:52
 * @since
 */
public class TCPTest2 {

    //客户端
    @Test
    public void client()  {
        Socket socket = null;
        OutputStream os = null;
        FileInputStream fileInputStream = null;
        InputStream inputStream =null;
        ByteArrayOutputStream byteArrayOutputStream =null;
        try {
            //1.客户端创建socket套接字
            socket = new Socket(InetAddress.getLocalHost(), 9090);
            //2.创建输出流
            os = socket.getOutputStream();
            //3.文件输入流,先把文件读入再让os写出去
            fileInputStream = new FileInputStream(new File("pic.jpeg"));
            //4.fileInputStream读文件然后os往出写文件
            byte[] bytes = new byte[512];
            int len;
            while((len = fileInputStream.read(bytes))!=-1)
            {
                os.write(bytes,0,len);
            }
            //当客户端传完数据之后shutdown一下,这样服务端就知道客户端传完了
            //服务端就不会一直等待
            socket.shutdownOutput();
            //5.等待服务端发来反馈,将其显示到控制台
            inputStream = socket.getInputStream();
            byteArrayOutputStream = new ByteArrayOutputStream();
            //6.inputStream读取来自服务端的信息
            //并通过baos将其输出到控制台
            byte[] bytes1 = new byte[3];
            int len1;
            while((len1=inputStream.read(bytes1))!=-1)
            {
                byteArrayOutputStream.write(bytes1,0,len1);
            }
            System.out.println(byteArrayOutputStream.toString());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(inputStream!=null){inputStream.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(byteArrayOutputStream!=null){byteArrayOutputStream.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fileInputStream!=null){fileInputStream.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(os!=null){os.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(socket!=null){socket.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    //服务端
    @Test
    public void server(){

        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream inputStream = null;
        FileOutputStream fileOutputStream = null;
        OutputStream outputStream =null;
        try {
            //创建serverSocket
            serverSocket = new ServerSocket(9090);
            socket = serverSocket.accept();

            //得到输入流,此时图片信息在输入流中
            inputStream = socket.getInputStream();
            //再通过FileOutputStream把图片文件保存
            fileOutputStream = new FileOutputStream(new File("TCP_pic.jpeg"));

            byte[] bytes = new byte[512];
            int len;
            //inputStream的read方法是一个阻塞式的方法
            while((len=inputStream.read(bytes))!=-1)
            {
                fileOutputStream.write(bytes,0,len);
            }

            //服务器端给客户端一个反馈
            outputStream = socket.getOutputStream();
            outputStream.write("资源已收到,接收成功".getBytes());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(outputStream!=null){outputStream.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(fileOutputStream!=null){fileOutputStream.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(inputStream!=null){inputStream.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(socket!=null){socket.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if(serverSocket!=null){serverSocket.close();}
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

}

该博客图片来源于尚硅谷宋老师教学课件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值