socket主要用于进程间,网络间通讯
一、socket基本例子
服务端:
/**
* socket 编程基础
* <p>Title: SocketService</p>
* <p>Description: </p>
* <p>Company: www.itcast.cn</p>
* @version 1.0
*/
public class SocketService {
//创建一个服务端,用于接收客户端请求
public static void main(String[] args) throws Exception {
//指定监听端口
int port = 8080;
//创建一个socket通讯服务
ServerSocket ssc = new ServerSocket(port);
System.out.println("server启动成功");
//接受请求
Socket socket = ssc.accept();
//使用流的形式读取客户端发送的消息
InputStream is = socket.getInputStream();
byte[] bytes = new byte[1024];
int len;
StringBuilder sb = new StringBuilder();
while((len=is.read(bytes))!=-1){
sb.append(new String(bytes, 0, len, "utf-8"));
}
System.out.println("接收到客户端消息--->"+sb.toString());
//关闭流
is.close();
socket.close();
ssc.close();
}
}
通过DEBUG可以发现服务启动后会等待客户端发送消息才会执行下一步
客户端:
public class ClientSocket {
public static void main(String[] args) throws Exception {
//指定address
String host = "127.0.0.1";
//指定服务端口
int port = 8080;
Socket socket = new Socket(host, port);
OutputStream os = socket.getOutputStream();
String b = "客户端向服务端发送消息";
os.write(b.getBytes("utf-8"));
os.close();
socket.close();
}
}
二、双向通讯
服务端:
当读取完客户端的消息后,打开输出流,将指定消息发送回客户端
public class SocketServer {
public static void main(String[] args) throws Exception {
//指定一个通讯用端口
int port = 8080;
ServerSocket ssc = new ServerSocket(port);
System.out.println("服务端启动。。");
Socket sc = ssc.accept();
InputStream is = sc.getInputStream();
int len;
byte[] bytes = new byte[1024];
StringBuilder sb = new StringBuilder();
while((len=is.read(bytes))!=-1){
sb.append(new String(bytes,0,len,"utf-8"));
}
System.out.println("服务端成功接受客户端发送消息--->"+sb.toString());
//回复接收成功消息
OutputStream os = sc.getOutputStream();
String ms = "已成功接受客户端消息";
os.write(ms.getBytes("utf-8"));
os.close();
is.close();
sc.close();
ssc.close();
}
服务端启动。。
服务端成功接受客户端发送消息--->客户端发送消息到服务端
客户端:
扫描二维码关注公众号,回复:
2192804 查看本文章
在发送完消息时,调用关闭输出流方法,然后打开输出流,等候服务端的消息。
/**
*
* <p>Title:双向通讯</p>
* <p>Description: </p>
* @version 1.0
*/
public class ClientServer {
public static void main(String[] args) throws Exception {
String host = "127.0.0.1";
int port = 8080;
Socket sc = new Socket(host, port);
OutputStream os = sc.getOutputStream();
String message = "客户端发送消息到服务端";
os.write(message.getBytes("utf-8"));
//关闭输出后续通讯只能接收消息
sc.shutdownOutput();
InputStream is = sc.getInputStream();
int len;
StringBuilder sb = new StringBuilder();
byte[] bytes = new byte[1024];
while((len=is.read(bytes))!=-1){
sb.append(new String(bytes,0,len,"utf-8"));
}
System.out.println("客户端接受服务器响应--->"+sb.toString());
is.close();
os.close();
sc.close();
}
控制台输出结果
客户端接受服务器响应--->已成功接受客户端消息
注意
正常来说,客户端打开一个输出流,如果不做约定,也不关闭它,那么服务端永远不知道客户端是否发送完消息,那么服务端会一直等待下去,直到读取超时。所以怎么告知服务端已经发送完消息就显得特别重要
比如上面双向通讯的例子里客户端如果在调用完输出流以后不执行socket.shutdownOutput()方法关闭输出流,则服务端就无法知道客户端消息是否发送,则会一直等待
缺点
但是这样操作虽然可以保证服务端可以知道客户端已经发送消息,但是由于关闭了socket的输出方式,所以后面如果客户端再向发送消息也无法完成,除非再次新建一个新的socket对象。对于频繁交互的时候肯定会存在问题