美文网首页
【Java学习】网络编程|socket入门——实现发送文字消息、

【Java学习】网络编程|socket入门——实现发送文字消息、

作者: 榆野铃爱 | 来源:发表于2019-08-21 21:13 被阅读0次

    心得感悟

    日常懵逼,但是多看几次,多写几次就好了。感觉编程最难的地方就是我们对程序很陌生,怕陌生的代码,还是要多练,编程有些东西真的是只可意会不可言传。觉得今天学的socket很有意思,因为它让程序不再是孤单的自己,它可以连接外面的世界,莫名感觉它很伟大。


    内容简概

    • 一、网络编程介绍
    • 二、Socket介绍
    • 三、用Socket实现数据传输
    • 四、运行效果

    具体内容

    一、网络编程介绍

    1. 什么是网络编程?
    网络编程的本质是两个设备之间的数据交换,即网络通信。通常,设备指的是计算机。

    2. 网络编程的模型
    在网络通信中主要有两种通信模式,一种是B/S结构(Browser/Server,浏览器/服务器模式),另一种是C/S结构(Client/Server,服务器/客户机模式)。B/S模式常见于我们使用的浏览器,我们点击进入一个网页,服务器就返回给我们信息。C/S模式常见于我们的端游、应用软件,我们直接在上面操作,不会访问到其他地方。在这里,我们着重讲C/S模式

    网络编程模式
    3. IP地址和域名
    IP地址是分配给用户上网使用的网际协议的设备的数字标签。在现实生活中,写信需要知道对方的地址,打电话需要知道对方的手机号码。互联网中也一样,网络中的数据传输就是通过获取每个设备的IP地址实现的。由于IP地址不便于阅读,于是某个聪明的人就想到给它取一个名字,这个名字就是域名。比如baidu.com就是一个域名。

    如何查看自己电脑的IP地址呢?
    win+R键打开搜索框,输入cmd进入命令提示符,最后输入ipconfig按下回车,就可以看到自己电脑的IP地址啦。

    IP地址

    4. 数据传输协议TCP/UDP
    TCP(传输控制协议):面向连接的 安全的
    UDP(用户数据报协议):面向无连接的 不安全 但速度快
    它们之间有什么关系呢?用一张图告诉你。

    关系图

    5. IP地址和端口号
    端口号:每个应用程序对应一个端口号,通过类似门牌号的端口号,客户端才能真正的访问到该服务器。使用端口号,可以找到一台设备上唯一的一个程序。所以如果需要和某台计算机建立连接的话,只需要知道IP地址或域名即可,但是如果想和该台计算机上的某个程序交换数据的话,还必须知道该程序使用的端口号。

    IP地址和端口号的关系

    二、Socket介绍

    1. 什么是Socket?
    套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。 简单来说是IP地址与端口的结合协议Socket = (IP地址:端口号)。套接字的表示方法是点分十进制的IP地址后面写上端口号,中间用冒号或逗号隔开。

    那socket和IP/TCP有什么关系吗?
    套接字可以看成是两个网络应用程序进行通信时,各自通信连接中的一个端点。通信时,其中的一个网络应用程序将要传输的一段信息写入它所在主机的Socket中,该Socket通过网络接口卡的传输介质将这段信息发送给另一台主机的Socket中,使这段信息能传送到其他程序中。因此,两个应用程序之间的数据传输要通过套接字来完成

    关系图

    2. Socket通信模式
    Socket可以实现网络间的数据传输,接下来我就将具体介绍编程中如何使用Socket。

    Socket通信模式

    三、用Socket实现数据传输

    1. Socket——客户端向服务器端发送固定信息
    下面这个例子是实现客户端向服务器端发送默认的信息。先简单了解一下服务器端和客户端的搭建。

    127.0.0.1是通用的本机IP地址。
    端口号一般用到的是1到65535,其中0不使用。一般的应用程序使用1024到4999用来通讯。5000以后的用来用户自定义端口。所以我们自己编程时尽量使用5000后的,避免端口被占用。

    // 模拟客户端
    class Client {
        public static void main(String[] args) throws IOException {
            // 1.创建用于通信的socket
            // 指明和谁通信:IP地址 端口号
            Socket socket = new Socket("127.0.0.1",8989);
    
            // 接收服务器端的数据
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    
            // 读取服务器端发来的数据
            String line = null;
            while ((line = br.readLine()) != null){
                System.out.println(line);
            }
    
            // 客户端向服务器端发送数据
            PrintStream ps = new PrintStream(socket.getOutputStream());
            ps.println("你好啊");
            socket.shutdownOutput();
        }
    }
    
    // 模拟服务器端
    class Server {
        public static void main(String[] args) throws IOException {
            // 1.创建服务器端的ServerSocket
            ServerSocket ss = new ServerSocket(8989);
    
            // 2.获取连接的客户端的socket
            Socket clientSocket = ss.accept();
    
            // 3.向客户端发送数据
            // 法一:BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
            //法二:
            PrintStream ps = new PrintStream(clientSocket.getOutputStream());
            ps.println("登陆成功");
    
            // 输出完毕
            clientSocket.shutdownOutput();
    
            // 4.接收客户端发来的数据
            BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            String  line = null;
            while ((line = br.readLine()) != null){
                System.out.println(line);
            }
        }
    }
    

    2. Socket——服务器端向客户端发送可变信息
    下面实现从终端向服务器端⼿动输⼊信息,服务器端会把输⼊的内容发送给客户端,可以⼀直发。

    class MyClient {
        public static void main(String[] args){
            // 链接服务器端的socket
            Socket socket = null;
            try {
                socket = new Socket("127.0.0.1",8888);
    
                // 接收服务器端信息
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    
                String line = null;
                while ((line = br.readLine()) != null){
                    System.out.println(line);
                }
    
                // 从键盘输入数据 发送给服务器端
            } catch (IOException e) {
                System.out.println("网络出错 请重新登录!");
            } finally {
                // 关闭连接
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    class MyServer {
        public static void main(String[] args){
            // 创建ServerSocket
            try(ServerSocket ss = new ServerSocket(8888)) {
                // 监听客户端的连接
                Socket socket = ss.accept();
    
                // 从终端接收数据
                BufferedReader keyin = new BufferedReader(new InputStreamReader(System.in));
                // 获取向客户端输出数据的输出流
                PrintStream ps = new PrintStream(socket.getOutputStream());
                String line = null;
    
                while ((line = keyin.readLine()) != null){
                    // 发送给客户端
                    ps.println(line);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    3. Socket——客户端向服务器端上传图⽚
    下面实现客户端向服务器端上传图⽚。建议使用jpg格式的图片。注意!音频图片一般都采用字节流传输,故输入输出时都需要用字节流,而不能用字符流

    class Client{
        public static void main(String[] args) throws IOException {
            // 连接服务器端  获取socket
            Socket socket = new Socket("127.0.0.1",8080);
    
            // 创建服务器端对应的输入流 用于接收服务器端发来的数据
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println(br.readLine());
    
            // 向服务器端发送文件(图片)
            // 1.将文件写入到内存里
            String path = "C:/Users/ASUS/Pictures/有空画画/20131108104858_uGFa5.jpeg";
            FileInputStream fis = new FileInputStream(path);
    
            // 2.创建字节流 outputStream
            BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
            byte[] buf = new byte[1024];
            int len = -1;
            while ((len = fis.read(buf)) != -1){
                bos.write(buf,0,len);
            }
            socket.shutdownOutput();
        }
    }
    
    class Server{
        public static void main(String[] args) throws IOException {
            ServerSocket ss = new ServerSocket(8080);
    
            // 监听客户端连接
            // 当有客户端连接服务器 就可以得到对应的socket对象
            // 无则等待
            Socket socket = ss.accept();
    
            // 创建客户端对应的输出流 用于向这个客户端发送数据
            PrintStream ps = new PrintStream(socket.getOutputStream());
            ps.println("连接成功 可以发数据了");
    
            // 接收客户端传递过来的图片
            BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
            String path = "F:/homework/java/day1/java/src/main/java/day12/media/1.jpeg";
            FileOutputStream fos = new FileOutputStream(path);
    
            byte[] buf = new byte[1024];
            int len = -1;
            while((len = bis.read(buf)) != -1){
                fos.write(buf,0,len);
            }
            socket.shutdownOutput();
        }
    }
    

    四、运行效果

    注意!运行时要先开启服务器,再运行客户端。下面的效果图与上述顺序相同。

    客户端向服务器端发送固定文字
    服务器端向客户端不断发消息
    客户端向服务器端上传图⽚

    相关文章

      网友评论

          本文标题:【Java学习】网络编程|socket入门——实现发送文字消息、

          本文链接:https://www.haomeiwen.com/subject/nefisctx.html