网络编程之socket

简介

socket编程也叫套接字编程,应用程序可以通过它发送或者接受数据。网络通信其实就是socket通信,通信的两端都要有socket,一般发起通信的一端叫客户端,等待通信的一端属于服务端。

原理

1、服务端新建一个socket,绑定地址和开启端口的监听,此时服务端进入阻塞状态,等待客户端的连接
2、客户端新建一个socket,实例化socket时关联服务端的ip,端口,连接服务端
3、服务端和客户端建立连接后就可以收/发数据
4、关闭连接

在这里插入图片描述

案例1

客户端给服务端发送消息

服务端

package com.tk.socket.demo01;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * @author taoke
 * @desc socket服务端,接收客户端发送的消息
 * @email 1504806660@qq.com
 * @date 2022/2/16
 */
public class SocketTcpServer {

    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream inputStream = null;
        try {
            System.out.println("服务端已启动~~~~");
            //开启本地端口9999的监听
            serverSocket = new ServerSocket(9999);
            阻塞,等待客户端的连接
            socket = serverSocket.accept();
            System.out.println("客户端连接成功~~~~");
            //从通道获取输入流
            inputStream = socket.getInputStream();
            int len;
            byte[] b = new byte[1024];
            //以字节流的形式读取客户端发送的消息
            while ((len = inputStream.read(b)) != -1) {
                System.out.println(new String(b, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            System.out.println("退出服务端~~~~");
            //释放资源
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (socket != null) {
                    socket.close();
                }
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端

package com.tk.socket.demo01;

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

/**
 * @author taoke
 * @desc socket客户端,给服务端发送消息
 * @email 1504806660@qq.com
 * @date 2022/2/16
 */
public class SocketTcpClient {

    public static void main(String[] args) {
        Socket socket = null;
        OutputStream outputStream = null;
        try {
            //连接服务端
            socket = new Socket(InetAddress.getLocalHost(), 9999);
            System.out.println("连接服务器成功~~~~~~");
            //从通道获取输出流
            outputStream = socket.getOutputStream();
            //给服务端发送消息
            outputStream.write("hello server,i am client".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            System.out.println("退出客户端~~~~");
            //释放资源
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果

1.服务端启动,进入阻塞状态,等待客户端的连接

在这里插入图片描述
2、客户端启动,连接服务端,给客户端发送消息
在这里插入图片描述
3、服务端成功接收到消息,退出程序
在这里插入图片描述

案例2

客户端给服务端发送消息,服务端收到消息后回复客户端

服务端

package com.tk.socket.demo02;

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

/**
 * @author taoke
 * @desc socket服务端,客户端给服务端发送消息,服务端收到消息后回复客户端
 * @email 1504806660@qq.com
 * @date 2022/2/16
 */
public class SocketTcpServer {

    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        try {
            System.out.println("服务端已启动~~~~");
            serverSocket = new ServerSocket(9999);
            socket = serverSocket.accept();
            System.out.println("客户端连接成功~~~~");
            inputStream = socket.getInputStream();
            int len;
            byte[] b = new byte[1024];
            while ((len = inputStream.read(b)) != -1) {
                System.out.println(new String(b, 0, len));
            }
            outputStream = socket.getOutputStream();
            outputStream.write("hello client,i am server".getBytes());
            //设置结束写入标记
            socket.shutdownOutput();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            System.out.println("退出服务端~~~~");
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
                if (socket != null) {
                    socket.close();
                }
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端

package com.tk.socket.demo02;

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

/**
 * @author taoke
 * @desc socket客户端,客户端给服务端发送消息,服务端收到消息后回复客户端
 * @email 1504806660@qq.com
 * @date 2022/2/16
 */
public class SocketTcpClient {

    public static void main(String[] args) {
        Socket socket = null;
        OutputStream outputStream = null;
        InputStream inputStream = null;
        try {
            socket = new Socket(InetAddress.getLocalHost(), 9999);
            System.out.println("连接服务器成功~~~~~~");
            outputStream = socket.getOutputStream();
            outputStream.write("hello server,i am client".getBytes());
            //设置结束写入标记
            socket.shutdownOutput();
            inputStream = socket.getInputStream();
            int len;
            byte[] b = new byte[1024];
            while ((len = inputStream.read(b)) != -1) {
                System.out.println(new String(b, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            System.out.println("退出客户端~~~~");
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果

1.服务端启动,进入阻塞状态,等待客户端的连接

在这里插入图片描述
2、客户端启动,连接服务端,给客户端发送消息,同时收到服务端回复的消息

在这里插入图片描述
3、服务端收到客户端的消息,然后给客户端发送消息

在这里插入图片描述

案例3

客户端用字符流的形式给服务端发送消息,服务端回复消息

服务端

package com.tk.socket.demo03;

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

/**
 * @author taoke
 * @desc socket服务端,用字符流的形式给客户端发送消息
 * @email 1504806660@qq.com
 * @date 2022/2/16
 */
public class SocketTcpServer {

    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        BufferedReader bufferedReader = null;
        BufferedWriter bufferedWriter = null;
        try {
            System.out.println("服务端已启动~~~~");
            //开启端口9999的监听
            serverSocket = new ServerSocket(9999);
            //阻塞,等待客户端的连接
            socket = serverSocket.accept();
            System.out.println("客户端连接成功~~~~");
            //通过字符流从通道读取服务端回复的消息
            InputStream inputStream = socket.getInputStream();
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String line = bufferedReader.readLine();
            System.out.println(line);
            //通过字符流将消息写入到通道
            OutputStream outputStream = socket.getOutputStream();
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
            bufferedWriter.write("hello client,i am server");
            bufferedWriter.newLine();//插入一个换行符,表示写入的内容结束,另一方必须使用readLine读取
            bufferedWriter.flush();//字符流需要手动把数据刷新到通道
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            System.out.println("退出服务端~~~~");
            try {
                if (bufferedWriter != null) {
                    bufferedWriter.close();
                }
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (socket != null) {
                    socket.close();
                }
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端

package com.tk.socket.demo03;

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

/**
 * @author taoke
 * @desc socket客户端,用字符流的形式给服务端发送消息
 * @email 1504806660@qq.com
 * @date 2022/2/16
 */
public class SocketTcpClient {

    public static void main(String[] args) {
        Socket socket = null;
        BufferedWriter bufferedWriter = null;
        BufferedReader bufferedReader = null;
        try {
            socket = new Socket(InetAddress.getLocalHost(), 9999);
            System.out.println("连接服务器成功~~~~~~");
            OutputStream outputStream = socket.getOutputStream();
            //通过字符流将消息写入到通道
            bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
            bufferedWriter.write("hello server,i am client");
            bufferedWriter.newLine();//插入一个换行符,表示写入的内容结束,另一方必须使用readLine读取
            bufferedWriter.flush();//字符流需要手动把数据刷新到通道
            //通过字符流从通道读取客户端回复的消息
            InputStream inputStream = socket.getInputStream();
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String line = bufferedReader.readLine();
            System.out.println(line);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {//释放资源
            System.out.println("退出客户端~~~~");
            try {
                if (bufferedWriter != null) {
                    bufferedWriter.close();
                }
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果

1.服务端启动,进入阻塞状态,等待客户端的连接
在这里插入图片描述
2、客户端以字符流的形式给服务端发送消息,服务端给客户端回复消息
在这里插入图片描述
3、服务端收到客户端的消息,给客户端回复消息

在这里插入图片描述

案例4

客户端发送文件,服务端接收文件,并且服务端回复消息

服务端

package com.tk.socket.demo04;

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

/**
 * @author taoke
 * @desc socket服务端,用字符流的形式给客户端发送消息
 * @email 1504806660@qq.com
 * @date 2022/2/16
 */
public class SocketTcpServer {

    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        ByteArrayOutputStream bas = null;
        try {
            System.out.println("服务端已启动~~~~");
            //1、开启端口9999的监听
            serverSocket = new ServerSocket(9999);
            //阻塞,等待客户端的连接
            socket = serverSocket.accept();
            System.out.println("客户端连接成功~~~~");
            //2、接收客户端发送的图片
            bis = new BufferedInputStream(socket.getInputStream());
            bas = new ByteArrayOutputStream();
            int len;
            byte[] b = new byte[1024];
            while ((len = bis.read(b)) != -1) {
                bas.write(b, 0, len);
            }
            //图片存放路径
            String destFilePath = "src\\temp.png";
            bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
            bos.write(bas.toByteArray());
            bos.flush();
            //3、向客户端发送消息,已收到图片
            bos = new BufferedOutputStream(socket.getOutputStream());
            bos.write("server: 收到图片".getBytes());
            bos.flush();
            socket.shutdownOutput();//设置结束写入标记 重要
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            System.out.println("退出服务端~~~~");
            try {
                //释放资源
                if (bos != null) {
                    bos.close();
                }
                if (bis != null) {
                    bis.close();
                }
                if (bas != null) {
                    bas.close();
                }
                if (socket != null) {
                    socket.close();
                }
                if (serverSocket != null) {
                    serverSocket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端

package com.tk.socket.demo04;

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

/**
 * @author taoke
 * @desc socket客户端,用字符流的形式给服务端发送消息
 * @email 1504806660@qq.com
 * @date 2022/2/16
 */
public class SocketTcpClient {

    public static void main(String[] args) {
        Socket socket = null;
        BufferedOutputStream bos = null;
        BufferedInputStream bis = null;
        FileInputStream fis = null;
        ByteArrayOutputStream bas = null;
        try {
            //1、连接服务器
            socket = new Socket(InetAddress.getLocalHost(), 9999);
            System.out.println("连接服务器成功~~~~~~");
            //2、向服务器发送图片
            //从通道获取输出流
            bos = new BufferedOutputStream(socket.getOutputStream());
            String filePath = "d:\\desk.png";//本地图片存放路径
            fis = new FileInputStream(filePath);//获取文件输入流
            bis = new BufferedInputStream(fis);//转换为缓存字节流
            bas = new ByteArrayOutputStream();//定义一个字节缓冲区
            //将读取到的文件写入缓冲区 bas
            byte[] b = new byte[1024];
            int i;
            while ((i = fis.read(b)) != -1) {
                bas.write(b, 0, i);
            }
            bos.write(bas.toByteArray());//字节缓冲区数据bas 写入通道
            bos.flush();//刷新
            System.out.println("图片发送成功");
            socket.shutdownOutput();//设置结束写入标记 重要
            //3、接收服务器回复的消息
            bis = new BufferedInputStream(socket.getInputStream());
            int len;
            byte[] buff = new byte[1024];
            while ((len = bis.read(buff)) != -1) {
                System.out.println(new String(buff, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {//释放资源
            System.out.println("退出客户端~~~~");
            try {
                //释放资源
                if (bos != null) {
                    bos.close();
                }
                if (bas != null) {
                    bas.close();
                }
                if (bis != null) {
                    bis.close();
                }
                if (fis != null) {
                    fis.close();
                }
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

运行结果

1.服务端启动,进入阻塞状态,等待客户端的连接
在这里插入图片描述
2、客户端向服务端发送图片,收到服务端回复的消息
在这里插入图片描述
3、服务端收到客户端的图片,保存到 "src"下
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值