Socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。网络上的两个程序通过一个双向的通讯连接实现数据的交换,这个双向链路的一端称为一个Socket,一个Socket由一个IP地址和一个端口号唯一确定。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 Socket是TCP/IP协议的一个十分流行的编程界面,但是,Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
Socket通讯过程:服务端监听某个端口是否有连接请求,客户端向服务端发送连接请求,服务端收到连接请求向客户端发出接收消息,这样一个连接就建立起来了。客户端和服务端都可以相互发送消息与对方进行通讯。
Socket的基本工作过程包含以下四个步骤:
1、创建Socket;
2、打开连接到Socket的输入输出流;
3、按照一定的协议对Socket进行读写操作;
4、关闭Socket。
以下是socket简单用例,包含客户端/服务器端实现。
package com.huatech.socket.constant; /** * socket常量类 * @author lh * @since 2017-06-04 * @version 1.0 * */ public final class SocketConstant { /** * socket host */ public static final String HOST = "127.0.0.1"; /** * socket port */ public static final int PORT = 2017; /** * socket charset */ public static final String CHARSET = "gb2312"; /** * socket timeout */ public static final int TIMEOUT = 5 * 1000; /** * socket 头部长度字节数 */ public static final int HEADER_LEN = 4; /** * socket 头部长度格式 */ public static final String HEADER_LEN_FORMAT = "%04d"; }
package com.huatech.socket.client; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import com.huatech.socket.constant.SocketConstant; /** * tcp/ip工具 * @author lh */ public class TcpClient { Socket sock = null; /** * 默认构造函数 */ public TcpClient() { } /** * 关闭socket通讯 * * @return */ public void close() { try { if (sock != null) { sock.close(); sock = null; } } catch (Exception e) { } } /** * 建立socket连接 * * @param addr * socket服务器地址 * @param port * socket服务器端口 * @return */ public void call(String host, int port) throws Exception { try { sock = new Socket(host, port); sock.setSoTimeout(SocketConstant.TIMEOUT); } catch (Exception e) { //logger.error("TCP_ERROR:通讯失败,原因{}",e); throw new RuntimeException("TCP_ERROR:通讯失败,请检查请求地址及端口号"); } } /** * 发送包文,在报头存在的情况下,先发送报头数据,再发送报文长度数据<br> * 报文长度的格式采用网络字节序,这里的实际长度以short限制为最大值(2字节) * @param str * 发送的包文内容,byte数组形式 * @return void - 无返回 */ public void sendMsg(byte[] b) throws RuntimeException { try { OutputStream out = sock.getOutputStream(); String sLen = String.format(SocketConstant.HEADER_LEN_FORMAT, b.length); out.write(sLen.getBytes(SocketConstant.CHARSET)); out.write(b); out.flush(); } catch (IOException e) { //logger.error("TCP_ERROR:发包失败{}",e); throw new RuntimeException("TCP_ERROR:发包失败"); } } /** * 接收应答包文,如果有报头,先读取报头,再读取长度部分<br> * 报文长度的格式采用网络字节序,这里的实际长度以short限制为最大值(2字节) * * @return byte[] - 收到的包文内容 */ public byte[] recvMsg() { String recv = ""; int tmpLen = 0; try { InputStream in = sock.getInputStream(); byte[] bts = new byte[SocketConstant.HEADER_LEN]; in.read(bts); // 获取包长 String strLen = new String(bts); int len = Integer.parseInt(strLen); byte[] buf = new byte[len]; while (true) { int iLen = in.read(buf); // 接收包体 tmpLen += iLen; if (iLen == -1) break; byte[] tmp = new byte[iLen]; System.arraycopy(buf, 0, tmp, 0, iLen); recv += new String(tmp, SocketConstant.CHARSET); if (tmpLen >= len) break; } return recv.getBytes(); } catch (Exception e) { // logger.error("TCP_ERROR:接收数据超时{}",e); throw new RuntimeException("TCP_ERROR:接收数据超时"); } } /** * 发送请求 * @param host * @param port * @param data * @return */ public String doSubmit(String host,int port,String data){ TcpClient tcpClient = new TcpClient(); try{ //连接服务器 tcpClient.call(host, port); //发送消息内容 System.out.println("请求的报文: "+data); //logger.info("请求的data:{}",data); tcpClient.sendMsg(data.getBytes(SocketConstant.CHARSET)); //发送完毕后接收 byte[] resBytes = tcpClient.recvMsg(); String result = new String(resBytes); //logger.info("返回的result:{}",result); System.out.println("返回的报文: "+result); return result; } catch (Exception e){ //logger.error("bank通信异常:", e); throw new RuntimeException("通信异常"); } finally{ tcpClient.close(); } } }
package com.huatech.socket.server; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; import com.huatech.socket.constant.SocketConstant; /** * TcpServer * @author lh * */ public class TcpServer { public void start(int port) { try { // 创建一个ServerSocket在 port 端口监听客户请求 @SuppressWarnings("resource") ServerSocket serverSocket = new ServerSocket(port); while (true) { // 侦听并接受到此Socket的连接,请求到来则产生一个Socket对象,并继续执行 Socket socket = serverSocket.accept(); /** 获取客户端传来的信息 */ // 由Socket对象得到输入流,并构造相应的BufferedReader对象 recvMsg(socket); //发送报文 sendMsg(socket, "hello Client, I am Server!".getBytes()); socket.close(); } } catch (Exception e) { System.out.println("Exception:" + e); } finally { // serverSocket.close(); } } /** * 发送包文,在报头存在的情况下,先发送报头数据,再发送报文长度数据<br> * 报文长度的格式采用网络字节序,这里的实际长度以short限制为最大值(2字节) * * @param str * 发送的包文内容,byte数组形式 * @return void - 无返回 */ public void sendMsg(Socket sock, byte[] b) throws RuntimeException { try { OutputStream out = sock.getOutputStream(); String sLen = String.format(SocketConstant.HEADER_LEN_FORMAT, b.length); out.write(sLen.getBytes(SocketConstant.CHARSET)); out.write(b); out.flush(); } catch (IOException e) { // logger.error("TCP_ERROR:发包失败{}",e); throw new RuntimeException("TCP_ERROR:发包失败"); } } /** * 接收应答包文,如果有报头,先读取报头,再读取长度部分<br> * 报文长度的格式采用网络字节序,这里的实际长度以short限制为最大值(2字节) * * @return byte[] - 收到的包文内容 */ public void recvMsg(Socket sock) { try { InputStream in = sock.getInputStream(); byte[] bts = new byte[SocketConstant.HEADER_LEN]; in.read(bts); // 获取包长 String strLen = new String(bts); int len = Integer.parseInt(strLen); byte[] buf = new byte[len]; in.read(buf); String recv = new String(buf, SocketConstant.CHARSET); System.out.println("客户端报文 : " + recv); } catch (Exception e) { // logger.error("TCP_ERROR:接收数据超时{}",e); throw new RuntimeException("TCP_ERROR:接收数据超时"); } } }
package com.huatech.socket; import com.huatech.socket.client.TcpClient; import com.huatech.socket.constant.SocketConstant; public class SocketClientTest { public static void main(String[] args) { TcpClient client = new TcpClient(); client.doSubmit(SocketConstant.HOST, SocketConstant.PORT, "hello, i am client!"); } }
package com.huatech.socket; import com.huatech.socket.constant.SocketConstant; import com.huatech.socket.server.TcpServer; public class SocketServerTest { public static void main(String[] args) { new TcpServer().start(SocketConstant.PORT); } }
附件为demo工程
相关推荐
基于python的程序设计。一个简单的python socket通信程序代码,主要演示socket如何使用
在OpenWrt的软路由上进行luci的自定义web界面开发,可实现自定义配置,以及其可视化修改,提供简单、易操作的配置修改功能。当然,这些功能的实现一方面基于OpenWrt自身软路由的特性,且可自行进行编译选择添加组件...
使用java socket实现服务器端与客户端的相互对话简单用例
参考本代码可熟悉socket基本使用方法、文件传输的基本功能实现,以及包含简单录音播放功能的2人聊天功能基本使用。 目录: code:源代码目录及工程可执行文件。 测试用例:包含正常功能,及非法入参测试,试用可执行...
为解决在网络环境复杂的条件下套接字传输数据被分块抵达,导致一次接收不能正确接收完的问题,封装了一个传输类模块,可以保证一次发送的数据,能被一次正确完全接收。...包含模块代码和用例,对外接口简单,使用方便
好东西大家分享 ,简单程序初学者适用.老师课堂示范用例,经典。
leetcode超时用例数 远程代码执行器 远程代码执行器的前端代码· 目录 关于该项目 这是远程代码执行器的前端代码。 这是我大学编码论坛分配的一个项目,类似于CodeChef和Leetcode等网站的在线IDE。 突出特点: 代码...
0.9版由于没有时间测试所以代码虽然可以编译通过但下载有问题,1.0版测试通过了,修改了0.9版中的几个问题:1.发送GET命令的字符串结尾掉了1个"\r\...代码中有一个简单的测试用例,并新增了几个log宏用来打印调试信息。
10、HTTP+Socket接口免编码:完全封装HTTP以及Socket接口,协议模板+纯关键字驱动,免编码,初级测试人员的福音,与其他类似开源工具相比优势明显11、在线调试用例:用例步骤管理界面直接调试自动化用例,避免使用...
常见用例 单进程应用服务器,例如免费的heroku.com帐户或类似的服务器 建立聊天 制作节点+ JavaScript游戏 安装 它作为npm软件包托管,因此安装当然很简单: yarn add socket-starter --save # you will also need ...
C# WebSocket 服务端和网页端示例,初学者必备!
Phoenix-Linux-SocketCAN-示例在Linux / RaspPi平台上使用CTRE Phoenix类库的一般示例。 演示了两个用例... 对于非FRC用例(将无线游戏手柄插入Raspberry PI中),运行没有roboRIO的机器人。 在FRC竞赛中使用roboRIO...
除了简单的例子,还有一些特别好的使用 AngularJS + Socket.io 的用例。 数组操作 我删除了这些函数,因为 Lo-Dash 已经提供了并且可以使用原生 JS 和 Lo-Dash 完成附加和前置。 下面是使用 Array.unshift 和 push...
这个带有 js 和 tomcat 8 的 web socket。 websockets的优势: WebSockets 的效率、简单性和更少的带宽 WebSockets 比轮询等其他解决方法更高效、更高效。 它们需要更少的带宽并减少延迟。 WebSockets 简化了实时...
最近帮一哥们做一个简单的通信演示小程序,重拾遗忘很久的Windows网络编程,通过此次演示程序的制作,对于TCP的三路握手、Socket的运用理解更加深入了,同时从文字上的阻塞与非阻塞到情真意切的感受到二者之间的差异...
observable-socket为用户提供输入主题,rxjs-websockets允许用户提供输入流作为参数,以允许用户选择具有适合其自身用例的语义的observable(可以使用实现与observable-socket相同的语义)。 使用observable-socket...
蜘蛛网站一个简单的爬虫应用程序,它使用 Socket.io 抓取提交的网站并更新结果去做: 添加测试用例使用引导程序添加样式更改为在 Socket.io 中使用 Angular JS 功能:爬虫跟踪外部 URL 功能:图像和文件预览(或缩略...
轻轻松松具有单个标头的现代C ++ 11本机,与操作系统无关的套接字库/启动程序代码包括特征简易:通过包含单个头文件开始使用简单的套接字功能可移植:在Windows和Linux上均可使用可配置:可以轻松地从头文件访问和...
2、专业用例管理:自动化用例的专业管理方式,让您编写自动化用例更简单,直观。 3、质量管理:Web端不仅仅有用来管理自动化相关的模块,更可以做一些简单的质量数据收集分析以及数据的多图表展示。 4、多线程执行...