Socket的入门案例(上)

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

       远程消息调用的底层使用的是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使用的一个入门,下一篇将在此基础上,进一步演化:服务器端接收到客户端发送过来的数据后,如何处理,涉及到服务器端(远程)方法(消息)的调用的原理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值