Socket网络编程

本文介绍了Socket网络编程的概念,包括C/S和B/S结构的区别,服务器的定义,通信的三大要素——协议、IP地址和端口号。接着详细阐述了如何使用Java实现简单的客户端和服务端的交互,包括客户端Socket的创建和数据收发,以及服务端ServerSocket的建立和响应。最后,文章通过文件上传案例展示了Socket在实际应用中的操作流程。

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

一.概念

软件结构
    C/S结构 :全称为Client/Server结构,是指客户端和服务器结构。常见程序有QQ、迅雷等软件。
    B/S结构 :全称为Browser/Server结构,是指浏览器和服务器结构。常见浏览器有谷歌、火狐等。

    两种架构各有优势,但是无论哪种架构,都离不开网络的支持。网络编程,就是在一定的协议下,实现两台计算机的通信的程序

一.服务器概念

     服务器指一个管理资源并为用户提供服务的计算机软件
     有一个计算机,不能叫服务器,只有装了服务器的软件才能叫服务器

二.通信三要素

1.协议:在传输数据的过程中需要遵守的规则

     TCP:面向连接的协议(3次握手)
            客户端---->服务端–>客户端向服务端请求连接
            客户端<----服务端–>服务端告诉客户端可以连接
            客户端---->服务端–>客户端直接连接服务端

            通信效率慢,没有大小的限制
            给两台计算机提供了一个可靠的通信,确保数据的完整性

     UDP:面向无连接协议 QQ 通信效率快 传输数据的时候,有大小限制 64KB
            不安全,容易丢失数据
            发送视频(网络视频,直播,不用等待你是否到场,我照播不误)

2 .IP地址:每台计算机的唯一标识号 TCP协议中的标识号就是IP地址
    IPV4:4个字节 --> 192.168.1.1
    一个小数点代表一个字节,一个字节由8个二进制位转成十进制得来的,最大是255->42亿+

            IPV6:16个字节,每一部分都是16进制—>比地球上的沙子都多(有点吹牛逼)

    cmd命令:

         ipconfig->查看自己的ip
         ping ip地址或者域名

     特殊地址:
        127.0.0.1–>代表的本机ip 我自己
        localhost

3 . 端口号:是每一个应用程序的唯一标识
     范围0-65535 前1024已经被占用


二.实现简单客户端和服务端的交互

一.编写客户端

客户端:Socket
    构造:
        Socket​(String host, int port)
                    host:连接服务端的ip地址
                    自己的计算机做服务器:127.0.0.1(localhost)
                    port:服务器设置的端口号
    步骤:
        1.创建Socket对象,指定要连接的服务器ip以及服务器设置的端口号
        2.调用Socket中的getOutputStream获取OutputStream,往服务器上发请求(写数据)
        3.调用Socket中国的getInputStream,读取服务端响应回来的结果(读数据)
        4.关流

 public static void main(String[] args) throws IOException {
        //创建Socket对象,指定要连接的服务器ip以及服务器设置的端口号
        Socket socket = new Socket("127.0.0.1",8888);

        //调用Socket中的getOutputStream获取OutputStream,往服务器上发请求(写数据)
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("这是客户端发送的请求!".getBytes());

        //调用Socket中国的getInputStream,读取服务端响应回来的结果(读数据)
        InputStream inputStream = socket.getInputStream();
        byte[] b = new byte[1024];
        int len = inputStream.read(b);
        System.out.println(new String(b,0,len));

        //关流
        inputStream.close();
        outputStream.close();
        socket.close();

    }

二.编写服务端

服务端:ServerSocket:
    构造:
        ServerSocket​(int port)
                    port:是服务器设置的端口号

    方法:
        Socket accept()–>等待接收连接服务端的客户端对象那个客户端连接我这个服务端,此方法返回的Socket对象就是哪个客户端的Socket对象

    步骤:
        1.创建ServerSoceket,设置自己的端口号
        2.调用accept方法获取连接服务端的客户端对象
        3.调用getInputStream用来读取客户端发来的请求数据(读数据)
        4.调用getOutputStream往客户端响应一条数据(写数据)
        5.关闭资源

public static void main(String[] args) throws IOException {
        //创建ServerSoceket,设置自己的端口号
        ServerSocket serverSocket = new ServerSocket(8888);
        //调用accept方法获取连接服务端的客户端对象
        Socket accept = serverSocket.accept();

        //调用getInputStream用来读取客户端发来的请求数据(读数据)
        InputStream inputStream = accept.getInputStream();
        byte[] b = new byte[1024];
        int len = inputStream.read(b);
        System.out.println(new String(b,0,len));

        //调用getOutputStream往客户端响应一条数据(写数据)
        OutputStream outputStream = accept.getOutputStream();
        outputStream.write("这是服务器返回的数据".getBytes());

        //关闭资源
        outputStream.close();
        serverSocket.close();
        inputStream.close();
        accept.close();
    }

三.文件上传案例

一.编写客户端

        步骤:
            1.创建Socket对象,指定服务端的ip以及端口号
            2.创建FileInputStream用于读取硬盘上的图片
            3.调用getOutputStream用于往服务端写我们读到的图片
            4.边读边写
            5.调用getInputStream.接收服务端响应回来的结果
            6.关闭资源

public static void main(String[] args) throws IOException {
		//创建Socket对象,指定服务端的ip以及端口号
        Socket socket = new Socket("127.0.0.1",9999);

        //创建FileInputStream用于读取硬盘上的图片
        FileInputStream fis = new FileInputStream("E:\\壁纸\\01.jpg");
        //调用getOutputStream用于往服务端写我们读到的图片
        OutputStream os = socket.getOutputStream();
        
        //边读边写
        byte[] b = new byte[1024];
        int len = 0;
        while ((len = fis.read(b)) != -1){
            os.write(b,0,len);
        }
        
		//通知服务端,我不写数据了,你别等着了,你继续往下执行吧
        socket.shutdownOutput();

        //调用getInputStream.接收服务端响应回来的结果
        InputStream is = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int read = is.read(bytes);
        System.out.println(new String(bytes,0,read));

		//关闭资源
        is.close();
        os.close();
        fis.close();
        socket.close();
    }

二.编写服务端:(多线程版)

        步骤:
            1.创建ServerSocket对象,设置端口号
            2.调用accept方法,等待接收连接过来的客户端对象
            3.调用getInputStream.读取客户端歇过来的图片
            4.创建FileOutputStream对象,往硬盘上的指定位置写图片数据
            5.边读边写
            6.调用getOputStream往客户端写数据->响应一个"文件上传成功"
            7.关闭资源

   Address already in use: JVM_Bind异常原因:连续来了2次服务器(端口号被占用)
public static void main(String[] args) throws IOException {
		//创建ServerSocket对象,设置端口号
        ServerSocket serverSocket = new ServerSocket(9999);
        while (true){
            new Thread(new Runnable() {
                Socket accept;
                InputStream is;
                FileOutputStream fos;
                OutputStream os;
                @Override
                public void run() {
                    try {
                    	//调用accept方法,等待接收连接过来的客户端对象
                        accept = serverSocket.accept();
                        
						//调用getInputStream.读取客户端歇过来的图片
                        is = accept.getInputStream();
                        //创建FileOutputStream对象,往硬盘上的指定位置写图片数据
                        String name = System.currentTimeMillis()+".jpg";
                        fos = new FileOutputStream("E:\\HeiMa\\"+name);

                        //边读边写
                        byte[] b = new byte[1024];
                        int len = 0;
                        while ((len = is.read(b)) != -1){
                            fos.write(b,0,len);
                        }
                        
						//调用getOputStream往客户端写数据->响应一个"上传成功"
                        os = accept.getOutputStream();
                        os.write("上传成功".getBytes());
                        
                    }catch (Exception e){
						e.printStackTrace();
                    }finally {
                        try {
                        	//关闭资源
                            if(os != null) os.close();
                            if(fos != null) fos.close();
                            if(is != null) is.close();
                            if(accept != null) accept.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值