Java Socket

Socket通信基本示例

SocketServer

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
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketServer {
public static void main(String[] args) throws IOException {
int port = 5555;//监听的端口
ServerSocket serverSocket=new ServerSocket(port);
System.out.println("正在服务端正在接受信息.....");
Socket socket=serverSocket.accept();
//建立好链接后,获取从Socket输入流
InputStream inputStream=socket.getInputStream();
byte[] bytes=new byte[1024];
int len;
StringBuffer sb=new StringBuffer();

while ((len=inputStream.read(bytes)) != -1){//read方法 从输入流读取一些字节数,并将它们存储到缓冲区 b 。
sb.append(new String(bytes,0,len,"UTF-8"));

}
System.out.println("get message from client"+sb.toString());
inputStream.close();
socket.close();
serverSocket.close();
}
}

SocketClient

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;

public class SocketClient {
public static void main(String[] args) throws IOException {
String host="127.0.0.1";
int port=5555;
//与服务端建立链接
Socket socket=new Socket(host,port);
OutputStream outputStream = socket.getOutputStream();

String message="我是客户端的信息";
outputStream.write(message.getBytes("UTF-8"));
outputStream.close();
socket.close();
}
}

结果显示

1
2
正在服务端正在接受信息.....
get message from client我是客户端的信息

消息通信优化

双向通信,发送消息并接受消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class SocketServer {
public static void main(String[] args) throws IOException {
int port = 5555;//监听的端口
ServerSocket serverSocket=new ServerSocket(port);
System.out.println("正在服务端正在接受信息.....");
Socket socket=serverSocket.accept();
//建立好链接后,获取从Socket输入流
InputStream inputStream=socket.getInputStream();
byte[] bytes=new byte[1024];
int len;
StringBuffer sb=new StringBuffer();
while ((len=inputStream.read(bytes)) != -1){
sb.append(new String(bytes,0,len,"UTF-8"));

}
System.out.println("get message from client"+sb.toString());
OutputStream outputStream=socket.getOutputStream();
String out="服务端收到你的信息";
outputStream.write(out.getBytes("UTF-8"));
inputStream.close();
socket.close();
serverSocket.close();
}
}

修改为,接收到信息后,发送信息给客户端。

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
public class SocketClient {
public static void main(String[] args) throws IOException {
String host="127.0.0.1";
int port=5555;
//与服务端建立链接
Socket socket=new Socket(host,port);
OutputStream outputStream = socket.getOutputStream();

String message="我是客户端的信息";
outputStream.write(message.getBytes("UTF-8"));
//通过shutdownOutput高速服务器已经发送完数据,后续只能接受数据
socket.shutdownOutput();
InputStream inputStream = socket.getInputStream();
byte[] bytes = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while ((len = inputStream.read(bytes)) != -1) {
//注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
sb.append(new String(bytes, 0, len,"UTF-8"));
}
System.out.println("get message from server: " + sb);


outputStream.close();
socket.close();
}
}

客户端修改为,发送完信息后,只接受数据。socket.shutdownOutput();

如何告知对方已发送完命令

其实这个问题还是比较重要的,正常来说,客户端打开一个输出流,如果不做约定,也不关闭它,那么服务端永远不知道客户端是否发送完消息,那么服务端会一直等待下去,直到读取超时。所以怎么告知服务端已经发送完消息就显得特别重要。

直接关闭socket

通过Socket关闭输出流的方式

1
socket.shutdownOutput();

调用Socket的shutdownOutput()方法,底层会告知服务端我这边已经写完了,那么服务端收到消息后,就能知道已经读取完消息,如果服务端有要返回给客户的消息那么就可以通过服务端的输出流发送给客户端,如果没有,直接关闭Socket。

通过约定符号

例如标记发送一行end则为客户端发送完毕