前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于Socket的解析以及双方通讯的java实现

关于Socket的解析以及双方通讯的java实现

作者头像
Mezereon
发布2018-09-13 13:32:12
9520
发布2018-09-13 13:32:12
举报
文章被收录于专栏:MyBlog

在Java编程之中,我们通常都会接触到网络编程,那么不可避免地就会接触到Socket通信,下面我将对Socket进行简单的解析,并给出双方通讯的代码实现方案

首先我们来介绍一下整个Socket的通信过程

Socket

  • 首先服务端先创建一个SocketServer,那么创建一个SocketServer需要我们指定端口号,如下
代码语言:javascript
复制
ServerSocket serverSocket=new ServerSocket(8888);

像上面这样我们就简单的开了一个端口号为8888的ServerSocket了

  • 接下来我们需要去接收来自客户端的连接请求,也就是图中的Other Socket,我们可以利用SockerServer的accept方法来建立连接,并且这个方法会返回一个Socket,用于和Other Socker进行通信,简单来说,我们就是利用SockerServer来获取Socket,然后利用这个Socket和别人通信
  • 接下来我们获取Socket的输入输出流,实现发送和接收信息,到此,我们已经知道两方进行Socket通信的基本思路了

接下来我们来看看关于ServerSocket以及Socket的一些关键方法

ServerSocket

首先我们看一下ServerSocket的构造方法,一共有4种:

  1. 无参的构造方法 : ServerSocket(), 返回没有绑定端口号的ServerSocket实例
  2. 含一个参数的构造方法 : ServerSocket(int port),返回绑定给定端口号的ServerSocket实例
  3. 含两个参数的构造方法 : ServerSocket(int port, int backlog),返回绑定给定端口号的ServerSocket实例,并且设定同步队列(syns queue)的大小
  4. 含三个参数的构造方法: ServerSocket(int port, int backlog, InetAddress bindAddr),返回绑定给定端口号的ServerSocket实例,并且设定同步队列(syns queue)的大小以及绑定给定的IP地址

主要看它的一些方法:

accept()

这个方法监听连接,一旦连接就返回一个Socket用于通信,需要注意的是,该方法为阻塞方法,如果没有连接程序并不会继续执行下去

close()

关闭Socket,如果accept还在阻塞的话,就会抛出一个SocketException的异常

关于ServerSocket就不多加赘述了,我们来看一看Socket


Socket

构造方法依然存在多种,这里只给出一个较为典型的

Socket(String host, int port),第一个参数是主机的IP地址作为字符串传入,第二个参数为端口号

getInputStream(), getOutputStream()

获得Socket的输入输出流,我们可以利用BufferReader以及PrintWriter来对这两个流进行操作,如下:

代码语言:javascript
复制
BufferReader reader = new BufferedReader(
                                new InputStreamReader(socket.getInputStream()));
PrintWriter  writer = new PrintWriter(
                                new OutputStreamWriter(socket.getOutputStream()));


下面简单编写一个双方互相通信的java实现

  • 首先是服务端
代码语言:javascript
复制
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
/**
 * Created by Mezereon on 2017/3/1.
 */
public class TCPServer {
    private Socket socket;
    private ServerSocket serverSocket;
    private BufferedReader reader;
    private PrintWriter writer;
    private Scanner scanner = new Scanner(System.in);
    //开启服务
    public void run() throws IOException {
            startTheSocket();
    }
    public void startTheSocket() throws IOException {
        serverSocket=new ServerSocket(18080); //打开18080端口等待连接
        acceptTheSocket();//接受连接并且初始化Socket,reader,writer
        openTheNewThreadToGetMessageFromClient();
        while(true) {      
              getYourMessage();//获取键盘数据并作为输入
        }
    }
    //接受连接并且初始化Socket,reader,writer
    private void acceptTheSocket() throws IOException {
        socket=serverSocket.accept();//阻塞方法,用于接受Socket连接
        System.out.println("Some one connect me ,it is "+socket.getLocalSocketAddress());//打印地址
        System.out.println("It's port is "+socket.getPort());//打印端口号
        reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));//获得输入流
        writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));//获得输出流
    }
    //扫描键盘并输入数据
    private void getYourMessage() throws IOException {
        String yourMessage = scanner.nextLine();
        checkYourMessage(yourMessage);//检查发送给客户端的信息
        writer.println(yourMessage);//发送信息
        writer.flush();//flush方法用于清空缓冲区,注意的是如果不flush你的信息可能发不出去一直存留在缓冲区
    }
    //用于检查是否退出
    private void checkYourMessage(String yourMessage) throws IOException {
        //关闭各种
        if (yourMessage.equals("exit")) {
            socket.close();
            writer.close();
            reader.close();
            System.exit(0);
        }
    }
    //开启一个新的线程来监听客户端发来的信息
    private void openTheNewThreadToGetMessageFromClient() throws IOException {
        //开启一个新的线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                getTheMessageFromClient();
            }
        }).start();

    }
    //不断循环来获取客户端发来的信息
    private void getTheMessageFromClient() {
        while(true) {
            String messageFromClient = null;
            try {
                messageFromClient = reader.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            printTheMessage(messageFromClient);//打印客户端发来的信息
        }
    }
    //打印客户端发来的信息
    private void printTheMessage(String messageFromClient) {
        if(messageFromClient!=null)
            System.out.println("He say:"+messageFromClient);
    }       
}

然后开始编写客户端:

代码语言:javascript
复制
import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created by Mezereon on 2017/2/27.
 */
public class TCPClient {

    private Socket socket;
    private BufferedReader reader ;
    private PrintWriter writer;
    private Scanner scanner = new Scanner(System.in);

    //开启Socket来连接
    public void run() throws IOException{
            startTheSocket();
    }

    //开始连接服务端
    private void startTheSocket() throws IOException{
            toConnectTheServer();//创建Socket并初始化
            openTheThreadToReceiveInfoFromServer();//开启一个新的线程来接受服务端发来的信息
            
            //一个循环,用于读取键盘的输入
            while(true) {
                String yourMessage = scanner.nextLine();
                //不为空则发送信息
                if(yourMessage!=null) {
                    writer.println(yourMessage);
                    writer.flush();//记得flush清空缓冲区
                }
                //判断是否退出
                if (yourMessage.equals("exit")) {
                    disConnect();
                    System.exit(0);
                }
            }
    }
    
    //创建一个Socket来连接本机的18080端口的服务端并初始化reader和writer
    private void toConnectTheServer() throws IOException {
        socket=new Socket("127.0.0.1",18080);
        reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        writer = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),true);
    }

    private void openTheThreadToReceiveInfoFromServer() throws IOException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    printMessage();//打印从服务端收到的信息
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    //循环不断读取服务端的信息
    private void printMessage() throws IOException {
        while (true) {
            String messageFromServer = null;
            try {
                messageFromServer = reader.readLine();//读取信息
                System.out.println("He say:" + messageFromServer);//打印信息
            } catch (IOException e) {
                e.printStackTrace();
            } catch (NullPointerException e) {

            }
            if(messageFromServer.equals("exit")){
                disConnect();//关闭连接
                System.exit(0);
            }
        }
    }

    //关闭各种
    private void disConnect() throws IOException {
        socket.close();
        reader.close();
        writer.close();
    }

}

至此,关于Socket通信简单的介绍以及利用java进行简单的通信的实现就结束了~

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.03.05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 首先我们来介绍一下整个Socket的通信过程
  • 接下来我们来看看关于ServerSocket以及Socket的一些关键方法
  • ServerSocket
    • accept()
      • close()
      • Socket
        • getInputStream(), getOutputStream()
        • 下面简单编写一个双方互相通信的java实现
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档