这里有新鲜出炉的 Java 并发编程示例,程序狗速度看过来!
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。
本篇文章主要介绍了关于 Socket 的解析以及双方通讯的 java 实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
在 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())); //获得输出流
- }
- //扫描键盘并输入数据
- 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 进行简单的通信的实现就结束了~
来源: http://www.phperz.com/article/17/1222/358083.html