socket 通讯简单的说,就是服务器监听端口,客户端根据服务器地址和端口发出请求,服务器处理请求后返回数据给客户端。比如说,需要开发一个简单的qq聊天室,客户端发出各种请求,加好友,发消息,网络视屏等等。服务器进过处理后,可以将消息进行转发给不同的客户端。
以下范例的目的是,从客户端发送数据,请求服务器执行指定方法,并且返回结果给客户端。 此范例一共包含3个java类。
首先给出我们的数据传输对象,Message类。
Message对象需要在网络中传输,因此必须可序列化,实现Serializable接口即可。简单起见,这个Message类只包装一个方法名,和一个String类型的参数。也就是说客户端指定一个方法名,并且提供一个String类型的参数,经过Message包装后,通过网络将请求数据传递给服务器。
先简单看下 java.net.ServerSocket,此类负责监听服务器端指定端口,当端口接受请求后,立即建立与客户端的连接。以下使用ServerListener类来对ServerSocket类进行包装。
此时启动main函数,ServerListener构造时初始化ServerSocket的一个实例,指定监听端口为 10008 。
之后调用service()方法进行对端口的监听。
socket = serverSocket.accept(); 服务器此时会处于监听状态,如果没有任何请求,线程会一直阻塞于此。假设此时有客户端进行请求,则会立即与客户端建立连接,并且得到一个socket连接对象。这个对象处位于 java.net.Socket. 得到socket连接对象后,即可进行对输入输出流进行一系列操作已完成数据传输。建立连接后,如果输入流没有任何请求数据,线程会阻塞,直到客户端发送请求数据。当请求数据到达服务器端时,服务器端从输入流中获得序列化对象,即Message对象,然后拆包后,根据方法名和参数进行对服务器端方法的调用,然后得到结果,写入输出流,返回给客户端对象。
最后给出客户端的java类,ClientListener.java 。
如果此时启动main函数,则会立即与服务器建立socket连接。在ClientListener类初始化的时候,已经实例化socket连接对象,指定服务器端地址和监听端口,并请求与服务器端的连接。建立连接后,客户端从命令行采集数据,如:method1:param1. 数据会被封装到Message对象,并且序列化后,通过之前建立起来的socket通道,传输到服务器端。这样就完成了客户端的数据采集和请求。其实,当从输入流获取返回结果时,客户端线程会阻塞等待服务器端的响应结果。服务器处理完毕,返回结果后,客户端立即打印出返回结果。
此范例执行过程:1,启动ServerListener,服务器端控制台显示 Server Listener Start ,local port = 10008
2,启动ClientListener,服务器控制台显示 Server Listener Start ,local port = 10008
Connection established : IP = /192.168.80.118 Port = 50360
3,客户端控制台输入 : method1:param1 . 服务器端显示 :
Begin to invoke method method1,with param param1
After invoking method method1
4,客户端显示:
The result from server after method invokation
Result is It's the result !!!!
To be continue ......