在Java编程之中,我们通常都会接触到网络编程,那么不可避免地就会接触到Socket通信,下面我将对Socket进行简单的解析,并给出双方通讯的代码实现方案
首先我们来介绍一下整个Socket的通信过程
首先服务端先创建一个SocketServer,那么创建一个SocketServer需要我们指定端口号,如下
1
|
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来对这两个流进行操作,如下:
1
2
3
4
|
BufferReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream()));
|
下面简单编写一个双方互相通信的java实现
首先是服务端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
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);
}
}
|
然后开始编写客户端:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
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.jianshu.com/p/af0b1a2300ce#