基于Java Socket编程的人工智障1.0

本文地址:https://heyzen.club/index.php/J/118.html
个人博客地址:https://heyzen.club/

近期,看到硬盘中存放的Java视频中有一个Java Socket编程。对,我没有打开之前不知道是关于什么的。一直以为Socket是锁(lock)。
这周末,也就是昨天和今天,对Java Socket编程有了一个初步的理解。

首先Socket,套接字,插座,就像他的翻译“插座”一样。是一种计算机与计算机沟通的枢纽。
Socket分为流式(SOCK_STREAM)套接字(面向连接,对应TCP协议),原始式套接字(SOCK_RAM)和包式套接字(这个名字暂且这样叫吧 对应网络传输的UDP协议)

思考
如何建立两个节点之间的网络连接?
如何向另外一个节点电脑发送信息?
如何从外部节点接受一个请求并给予响应?
如何应用网络协议编程?

连接请求
接受请求
连接成功
发送信息
接收信息
关闭连接

在Java中在java.net这个包中。
现在的网络编程架构一般为 B/S架构。

TCP协议,数据可靠传递。
UDP协议:数据不可靠传输,代价小,效率高,数据安全性不高
流式套接字

服务器端处理顺序
(1)建立一个服务器Socket绑定指定端口并开始监听
(2)使用accept()方法阻塞等待监听,获得新的连接
(3)建立输入输出流
(4)在已有的协议上产生会话
(5)使用close()关闭流和Socket

客户端处理顺序
(1) 建立客户端Socket连接,指定服务器的位置以及端口
(2) 得到Socket的读写流
(3) 利用流按照一定的协议对Socket进行读/写操作
(4) 使用close()关闭流和Socket

传输的时候,可以传入字符串,也可以传入对象(传对象的时候需要实现序列化),但是使用的是不同的流。关于流,这是我近期要补的知识了。因为之前学的时候没有听这一部分。

此时服务器是单用户机制,而一般服务器肯定是多用户访问的,所以此时可以使用多线程。
服务器一直监听
一个socket对应一个线程

如何在服务器获得每个客户端的IP地址
(1)InetAdress类:表示互联网协议地址,包含IP地址。是Java对IP地址的封装。

服务器端代码

package server;

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

/**
 * @author Zen
 * @version $Id: ServerThread.java, v 0.1 2018/12/22 3:51 Zen Exp $
 */
public class ServerThread extends Thread{
    //和本线程相关的Socket
    Socket socket = null;
    public ServerThread(Socket socket){
        this.socket = socket;
    }

    //线程启动
    public void run(){
        try {
            /*//1.建立一个服务器Socket绑定端口,并指定1219端口监听
            ServerSocket serverSocket = new ServerSocket(8800);
            //2.使用accept()方法阻塞等待监听,获得新的连接
            Socket socket = serverSocket.accept();*/
            //3.获得输入流
            //4.读取用户输入信息
            InputStream inputStream = socket.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            OutputStream outputStream = socket.getOutputStream();
            PrintWriter printWriter = new PrintWriter(outputStream);
            String info = null;
            String reply = null;
            while (!((info = bufferedReader.readLine()) == null)) {
                reply = info;
                System.out.println("收到客户端请求信息:" + info);
            }
            reply = reply.replace("吗", "");
            reply = reply.replace("?", "!");
            reply = reply.replace("?", "!");
            printWriter.write(reply);
            printWriter.close();
            outputStream.close();
            bufferedReader.close();
            inputStream.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

客户端代码

package client;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * @author Zen
 * @version $Id: AIChatClient.java, v 0.1 2018/12/22 2:30 Zen Exp $
 */
public class AIChatClient {
    public static void main(String[] args) {

            try {
                //(1) 建立客户端Socket连接,指定服务器的位置以及端口
                boolean flag=true;
                while(flag) {
                Socket socket = new Socket("localhost", 8800);
                //(2) 得到Socket的读写流

                    OutputStream outputStream = socket.getOutputStream();
                    PrintWriter printWriter = new PrintWriter(outputStream);
                    //输入流
                    InputStream inputStream = socket.getInputStream();
                    BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
                    //(3) 利用流按照一定的协议对Socket进行读/写操作
                    Scanner scanner = new Scanner(System.in);
                    String info = scanner.next();
                    if(info.equals("quit")){
                        System.out.println("系统正在退出...");
                        Thread.sleep(500);
                        System.out.println("系统退出成功");
                        break;
                    }
                   /* System.out.println("客户端:" + info);*/
                    printWriter.write(info);
                    printWriter.flush();
                    socket.shutdownOutput();
                    //接受服务器的响应并且打印显示
                    String reply;
                    while (!((reply = br.readLine()) == null)) {
                        System.out.println("智障1.0:" + reply);
                    }
                    //关闭资源
                    br.close();
                    inputStream.close();
                    printWriter.close();
                    socket.close();
                }
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }

    }
}

多线程

/**
 * eigpay.com Inc.
 * Copyright (c) 2013-2018 All Rights Reserved.
 */
package Thread;

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

/**
 * @author Zen
 * @version $Id: ServerThread.java, v 0.1 2018/12/22 3:51 Zen Exp $
 */
public class ServerThread extends Thread{
    //和本线程相关的Socket
    Socket socket = null;
    public ServerThread(Socket socket){
        this.socket = socket;
    }

    //线程启动
    public void run(){
        try {
            /*//1.建立一个服务器Socket绑定端口,并指定1219端口监听
            ServerSocket serverSocket = new ServerSocket(8800);
            //2.使用accept()方法阻塞等待监听,获得新的连接
            Socket socket = serverSocket.accept();*/
            //3.获得输入流
            //4.读取用户输入信息
            InputStream inputStream = socket.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            OutputStream outputStream = socket.getOutputStream();
            PrintWriter printWriter = new PrintWriter(outputStream);
            String info = null;
            String reply = null;
            while (!((info = bufferedReader.readLine()) == null)) {
                reply = info;
                System.out.println("收到客户端请求信息:" + info);
            }
            reply = reply.replace("吗", "");
            reply = reply.replace("?", "!");
            reply = reply.replace("?", "!");
            printWriter.write(reply);
            printWriter.close();
            outputStream.close();
            bufferedReader.close();
            inputStream.close();
            socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

基于UDP协议,就没写人工智障了,只是做了一个小Demo。

DatagramPacket 数据包。封装二零数据的长度,目标地址和目标端口。
DatagramSocket 发送和接受数据包的套接字

构造方法

客户端 服务器端
1.创建接受方服务器套接字,并绑定端口号
2.确定数据包接受的数据的数组大小
3.创建接受类型的数据包,数据将存储在数组中
4.通过套接字接受数据
5.及解析发送方发送的数据
6.释放资源

客户端
1.确定发送给服务器的信息,服务器地址以及端口
2.创建数据包,发送指定长度的信息到指定服务器的指定端口
3.创建DatagramSocket对象
4.向服务器发送数据包
5.释放资源

URL URLConnection

用户登录
多用户登录
持续请求

基于UDP协议
无连接
投出数据包
数据安全性不佳

java.net
DatagramPacket 数据包封装了数据、数据长度、
DatagramSocket 不维护连接状态 也不产生输出输出流

服务器端代码

package UDP;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketAddress;
import java.net.SocketException;

/**
 * @author Zen
 * @version $Id: AIChatServer.java, v 0.1 2018/12/22 15:46 Zen Exp $
 */
public class AIChatServer {
    public static void main(String[] args) {
        try {
            //1.创建接受方套接字。并指定端口号
            DatagramSocket datagramSocket = new DatagramSocket(8800);
            //2.确定数据包接受的数据的数组大小
            byte[] buf=new byte[1024];
            //3.创建接受类型的数据包,数据将存储在数组中
            DatagramPacket datagramPacket = new DatagramPacket(buf,buf.length);
            //4.通过套接字接受数据
            datagramSocket.receive(datagramPacket);
            //5.解析发送方发送的数据
            String message = new String(buf,0,buf.length);
            System.out.println(message);
            //响应
            String reply = "您好,在的。";
            byte [] replys = reply.getBytes();
            SocketAddress socketAddress = datagramPacket.getSocketAddress();
            DatagramPacket dp2 = new DatagramPacket(replys,replys.length,socketAddress);
            datagramSocket.send(dp2);
            //6.释放资源
            datagramSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户端代码

/**
 * eigpay.com Inc.
 * Copyright (c) 2013-2018 All Rights Reserved.
 */
package UDP;

import java.io.IOException;
import java.net.*;

/**
 * @author Zen
 * @version $Id: AIChatClient.java, v 0.1 2018/12/22 15:47 Zen Exp $
 */
public class AIChatClient {
    public static void main(String[] args) {
        //确定发送给服务器的信息,服务器地址以及端口
        String mess = "你好,我想咨询一个问题";
        byte[] buf = mess.getBytes();
        InetAddress inetAddress =null;
        try {
            inetAddress=InetAddress.getByName("localhost");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        int port = 8800;
        //创建数据包,发送指定长度的信息到指定服务器的指定端口
        DatagramPacket datagramPacket = new DatagramPacket(buf,buf.length,inetAddress,port);
        //创建DatagramSocket对象
        DatagramSocket datagramSocket = null;
        try {
            datagramSocket = new DatagramSocket();
        } catch (SocketException e) {
            e.printStackTrace();
        }
        //向服务器发送数据包
        try {
            datagramSocket.send(datagramPacket);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //接收服务器响应
        byte[] buf2 = new byte[1024];
        DatagramPacket dp2 = new DatagramPacket(buf2,buf2.length);
        try {
            datagramSocket.receive(dp2);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String reply = new String(buf2,0,buf2.length);
        System.out.println(reply);
    }
}

先总结一下就这样吧,之后写一篇文章,标题就叫做。我一个人利用AI核心开源代码,结合Java Socket编程,写了一个人工智能机器人。

https://heyzen.club/index.php/J/118.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章