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如何使用
例如,阻塞IO简单易用,但会阻塞进程直到数据准备就绪;非阻塞IO不会阻塞,但需要轮询检查;IO复用允许同时监视多个文件描述符,提高效率;信号驱动IO则通过信号通知IO完成;异步IO完全由内核管理,提供最高效率。`...
- 为确保通信正常,需要编写测试用例,模拟不同的网络环境,如网络延迟、断开连接等。 - 可使用网络抓包工具(如Wireshark)来查看数据传输过程,帮助定位问题。 以上知识点涵盖了Java和C#之间基于Socket通信的...
在IT领域,网络通信是不可或缺的一部分...这个资源为初学者提供了一个简单的起点,帮助理解TCP文件传输的机制。在实际项目中,还需要考虑更多的因素,如错误恢复、流量控制、并发处理等,以实现更健壮的文件传输系统。
本文将深入探讨C#环境下如何利用Tcp Socket进行简单高效的通信,结合提供的"SimpleSocket-master"源码,我们将揭示其方便易用的特点。 首先,TCP是一种面向连接的、可靠的传输协议,它确保数据的顺序传输和无丢失性...
5. **测试支持**:压缩包中的"Test"文件夹可能包含了Socketlib的测试用例,这些测试代码可以帮助开发者理解如何正确使用库,并验证其功能是否正常。通过这些测试,开发者可以确保在实际项目中引入Socketlib时,它的...
2. **SuperSocket库**:SuperSocket是一个强大的.NET Socket服务端开发框架,它提供了一种简单的方式来创建自定义的Socket服务。SuperSocket支持多种协议,允许开发者轻松实现TCP/IP通信,而无需深入理解网络编程的...
- 这可能是项目的测试模块,包含测试用例或者示例代码,用于验证摄像头数据通过Socket发送的逻辑是否正确。通常,这样的测试会模拟服务器端的行为,接收来自客户端的图像数据,并检查其完整性。 总之,"摄像头通过...
本项目“基于socket的计算器”就是这样一个实例,它展示了如何利用Socket技术来构建一个简单的计算服务,使得客户端能够发送计算请求,服务器端接收到请求后进行计算,并将结果返回给客户端。以下是对这个项目的详细...
- "SocketTest"可能是示例代码或测试用例,用于演示如何创建和使用Socket进行通信。通常,它会包含客户端和服务器端的代码,模拟实际的交互过程,帮助开发者理解Socket通信的基本步骤。 6. **拓展应用** - Socket...
可以使用命令行工具或者简单的用户界面进行测试,同时利用日志记录功能帮助调试。 以上就是基于Java Socket的聊天系统的主要知识点。这个项目对于初学者来说,是一个很好的实践平台,能够学习到网络编程的基本原理...
"简单的基于MFC的Socket点对点对话客户端" 指的是一个使用Microsoft Foundation Classes (MFC)库开发的简单Socket通信程序,该程序设计用于实现两个设备之间的点对点对话。MFC是微软提供的一套C++类库,它简化了...
通过分析和运行这些代码,学习者可以深入理解socket通信的工作原理,以及如何构建简单的聊天应用。 总的来说,基于socket的本地客户端与服务器通信是一个基础但实用的IT技能,对于理解和开发网络应用至关重要。它...
Socket.IO 是一个实时应用框架,它为开发人员提供了一种简单的方式来实现实时、双向通信。这个框架在浏览器和服务器之间构建了一座桥梁,使得数据能够实时、可靠地传输。Socket.IO 支持多种传输机制,包括 WebSocket...
在实际项目中,可能会包含多个文件,如服务器端的`ServerSocket`实现、客户端的`Socket`实现,以及可能的辅助类或测试用例。 由于压缩包文件列表中只有一个"Ha",可能是由于信息不完整。通常,一个完整的Java ...
心跳包通常包含简单的标识信息,如时间戳或序列号,不需要对方做出复杂的响应。如果一方在一定时间内未收到心跳包,可以认为网络连接已断开,从而触发重连操作。 4. **断线重连机制**: 断线重连是网络编程中的...
可以使用Test类作为测试基础,创建测试用例,模拟真实环境下的交互。 总之,基于protobuf的socket通信在Android中能够提供高效、简洁的数据交换方式。通过protobuf定义数据结构,使用socket进行网络通信,可以构建...
Socket.IO 是一个实时应用框架,它为Web开发者提供了一种简单、强大且可靠的在客户端与服务器之间进行实时双向通信的方法。"socket.io-client-master" 是 Socket.IO 的客户端库的源码仓库,通常用于开发需要实时交互...