在Java编程之中,我们通常都会接触到网络编程,那么不可避免地就会接触到Socket通信,下面我将对Socket进行简单的解析,并给出双方通讯的代码实现方案
首先我们来介绍一下整个Socket的通信过程
首先服务端先创建一个SocketServer,那么创建一个SocketServer需要我们指定端口号,如下
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来对这两个流进行操作,如下:
BufferReader reader = new BufferedReader( new InputStreamReader(socket.getInputStream())); PrintWriter writer = new PrintWriter( new OutputStreamWriter(socket.getOutputStream()));
下面简单编写一个双方互相通信的java实现
首先是服务端
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()));//获得输出流 } //扫描键盘并输入数[email protected]*码网据 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); } }
然后开始编写客户端:
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进行简单的通信的实现就结束了~
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持gaodaima编程笔记。