您的位置:首页 > 其它

Socket的入门案例(上)

2018-01-03 15:29 309 查看
       上一篇说到了如何开发高并发的应用,但篇幅所限有很多细节没有展开,此篇就远程消息调用的底层原理做以阐述。

       远程消息调用的底层使用的是Socket通信技术。对于计算机通信来说,一共划分了7层体系标准。在这个体系标准中,每个分层都接收有它下一层所提供的特定服务。上下层之间进行交互时所遵循的约定叫做“接口”,同一层之间的交互遵循的约定的协议叫做“协议”。这七层分别是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。而Socket通信技术是属于这七层标准中的应用层的技术,我们在使用Socket进行通信的时候,实际上是在调用java封装好的接口完成底层数据的通信,Socket通信的接口封装并屏蔽很多通信的细节,对于程序员来说也无需关心底层的细节。在Socket技术中,有两个角色,分别是服务器和客户,理解了这两个通信的角色的任务和通信步骤,就明白了Socket技术。原理如下表(注意序号的顺序)。

  

客户端
服务端
 1.创建一个ServerSocket,绑定到服务器的一个端口进行通信,并开启了服务器
 2.循环调用Socket.accept(),等待客户端接入
3.创建Socket对象,向服务器发出请求建立连接 
4.链接建立后,从Socket中获取输入输出流,
Socket.getInputStream()

Socket.getOutputStream()

向Socket的输出流中放进数据

 
 5.当有客户端接入,启动一个新的线程,运行通信任务
 6.从Socket中获取输入输出流,从Socket的输入流中获取客户端传递过来的数据,并进行处理,然后放到Socket的输出流中
7.接收到服务器端的数据后,返回,通信结束 
      代码如下:

  服务器端代码:ServerService.class

public class ServerService {
public static void main(String[] args) throws IOException {
// 创建一个ServerSocket,绑定到服务器的3366端口上
ServerSocket server = new ServerSocket();
server.bind(new InetSocketAddress("localhost", 3366));
System.out.println("服务器开启了");

//服务器一直等着接受客户端的接入请求
while (true) {
//Socket.accept()方法是一个阻塞方法,会一直等待客户端
Socket socket = server.accept();
//当有客户端请求,启动服务器上的线程去执行任务,此时服务器继续等待客户端接入
System.out.println("启动了一个线程负责通信");
new Thread(new ServerTask(socket)).start();
}
}
}
  
   线程任务:ServerTask.class

public class ServerTask implements Runnable{

Socket socket ;
InputStream in=null;
OutputStream out = null;

public ServerTask(Socket socket) {
this.socket = socket;
}

@Override
public void run() {
try {
//从socket连接中获取到与client之间的网络通信输入输出流
in = socket.getInputStream();
out = socket.getOutputStream();

//1.从网络通信输入流中读取客户端发送过来的数据
//将Socket输入流中的数据(客户端发送过来的数据在in中)用BufferedReader重新包装一下
//这样可以利用BufferedReader的方法按行读取
BufferedReader br = new BufferedReader(new InputStreamReader(in));

//注意:socketinputstream的读数据的方法都是阻塞的
//阻塞的意思:没有接受到数据的时候,服务端这个线程任务什么也不做,一直等待
String param = br.readLine();
System.out.println("服务端收到客户端信息:"+param);
//2.将调用结果写到sokect的输出流中,以发送给客户端
//将Socket输出流用PrintWriter重新包装一下
PrintWriter pw = new PrintWriter(out);
pw.println(param+" java");
pw.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
try {
in.close();
out.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}


   客户端:ClientService.class

public class ClientService {

public static void main(String[] args){

Socket socket = null;
InputStream inputStream = null;
OutputStream outputStream = null;
try {
//创建Socket对象,向服务器发出请求建立连接
socket = new Socket("localhost", 3366);

// 从socket中获取输入输出流
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();

//通过Socket输出流,向服务器发送信息
PrintWriter pw = new PrintWriter(outputStream);
pw.println("hello");
pw.flush();
System.out.println("客户端发送了字符:hello");

//在没收到服务器端的返回信息前,客户端一直阻塞
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
String result = br.readLine();
System.out.println("客户端收到服务端的信息:"+result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
try {
//完成通信
inputStream.close();
outputStream.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

       此篇对Socket通信的基础做了介绍,但是仅仅是对Socket使用的一个入门,下一篇将在此基础上,进一步演化:服务器端接收到客户端发送过来的数据后,如何处理,涉及到服务器端(远程)方法(消息)的调用的原理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: