java中的socket(01)

学习socket的起因

原因就是工作中有个项目要用到socket,第一次听到socket这个词的时候一脸懵逼,java中还有这玩意?不都是SSM一套用HTTP请求吗?怎么还有socket这个玩意?

socket是什么?

摘自百度百科:

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。

才疏学浅,个人没办法明确描述socket是什么。不过定义不重要,重要的是如何使用它。

如何使用socket?

创建socket服务端

服务端多线程处理客户端请求

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
/** 
* 该类为多线程类,用于服务端
*/
public class ServerThread implements Runnable {

private Socket client = null;
public ServerThread(Socket client){
this.client = client;
}

@Override
public void run() {
try{
//获取Socket的输出流,用来向客户端发送数据
PrintStream out = new PrintStream(client.getOutputStream());
//获取Socket的输入流,用来接收从客户端发送过来的数据
BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
boolean flag =true;
while(flag){
//接收从客户端发送过来的数据
String str = buf.readLine();
if(str == null || "".equals(str)){
flag = false;
}else{
if("bye".equals(str)){
flag = false;
}else{
//将接收到的字符串前面加上echo,发送到对应的客户端
out.println("echo:" + str);
}
}
}
out.close();
client.close();
}catch(Exception e){
e.printStackTrace();
}
}
}

开启服务端

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Server1 {  
public static void main(String[] args) throws Exception{
//服务端在20006端口监听客户端请求的TCP连接
ServerSocket server = new ServerSocket(20006);
Socket client = null;
boolean f = true;
while(f){
//等待客户端的连接,如果没有获取连接
client = server.accept();
System.out.println("与客户端连接成功!");
//为每个客户端连接开启一个线程
new Thread(new ServerThread(client)).start();
}
server.close();
}
}

编写socket客户端

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
public class Client1 {  
public static void main(String[] args) throws IOException {
//客户端请求与本机在20006端口建立TCP连接
Socket client = new Socket("127.0.0.1", 20006);
client.setSoTimeout(10000);
//获取键盘输入
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
//获取Socket的输出流,用来发送数据到服务端
PrintStream out = new PrintStream(client.getOutputStream());
//获取Socket的输入流,用来接收从服务端发送过来的数据
BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream()));
boolean flag = true;
while(flag){
System.out.print("输入信息:");
String str = input.readLine();
//发送数据到服务端
out.println(str);
if("bye".equals(str)){
flag = false;
}else{
try{
//从服务器端接收数据有个时间限制(系统自设,也可以自己设置),超过了这个时间,便会抛出该异常
String echo = buf.readLine();
System.out.println(echo);
}catch(SocketTimeoutException e){
System.out.println("Time out, No response");
}
}
}
input.close();
if(client != null){
//如果构造函数建立起了连接,则关闭套接字,如果没有建立起连接,自然不用关闭
client.close(); //只关闭socket,其关联的输入输出流也会被关闭
}
}
}

使用socket的个人体会

  1. 写出一个简单的服务端/客户端Demo很容易,实际使用并不简单
  2. socket和HTTP不同,HTTP有请求就有响应,而socket可以没有响应。又或者说socket根本就没有响应这个概念。因为socket是全双工的,所以它的请求和响应都一样。这就需要在使用过程中分辨请求和响应。
  3. socket必须要鉴权,在第一次使用socket的时候我就在想,这不是只要我开放了端口谁都可以连接上我的socket服务端吗?所以用socket一定要鉴权,对非法连接拒之门外(虽然我不知道的怎么做,但是一定要做)。
  4. socket读取数据十分麻烦,TCP/IP是传输层协议,而HTTP是应用层协议,两者分工不同。自然造就就读取数据的差异。使用socket必须事事亲力亲为,否则什么都办不成。

参考链接

java tcp socket编程
TCP/IP和socket的关系
TCP/IP和HTTP协议的区别