`
hbxflihua
  • 浏览: 662067 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

socket简单用例

阅读更多

  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编写的socket测试用例,简单的socket程序

    基于python的程序设计。一个简单的python socket通信程序代码,主要演示socket如何使用

    Socket编程-tcp&udp-测试用例.docx

    在OpenWrt的软路由上进行luci的自定义web界面开发,可实现自定义配置,以及其可视化修改,提供简单、易操作的配置修改功能。当然,这些功能的实现一方面基于OpenWrt自身软路由的特性,且可自行进行编译选择添加组件...

    socket实例

    使用java socket实现服务器端与客户端的相互对话简单用例

    C语言socket实现2人即时聊天系统_Linux服务器端Windows客户端

    参考本代码可熟悉socket基本使用方法、文件传输的基本功能实现,以及包含简单录音播放功能的2人聊天功能基本使用。 目录: code:源代码目录及工程可执行文件。 测试用例:包含正常功能,及非法入参测试,试用可执行...

    阻塞式socket套接字网络通信模块

    为解决在网络环境复杂的条件下套接字传输数据被分块抵达,导致一次接收不能正确接收完的问题,封装了一个传输类模块,可以保证一次发送的数据,能被一次正确完全接收。...包含模块代码和用例,对外接口简单,使用方便

    java IO流+socket源码 实现简单文本传输

    好东西大家分享 ,简单程序初学者适用.老师课堂示范用例,经典。

    leetcode超时用例数-remote-code-frontend:远程代码前端

    leetcode超时用例数 远程代码执行器 远程代码执行器的前端代码· 目录 关于该项目 这是远程代码执行器的前端代码。 这是我大学编码论坛分配的一个项目,类似于CodeChef和Leetcode等网站的在线IDE。 突出特点: 代码...

    C语言编写的HTTP下载库 1.0版

    0.9版由于没有时间测试所以代码虽然可以编译通过但下载有问题,1.0版测试通过了,修改了0.9版中的几个问题:1.发送GET命令的字符串结尾掉了1个"\r\...代码中有一个简单的测试用例,并新增了几个log宏用来打印调试信息。

    LuckyFrameWeb测试平台-其他

    10、HTTP+Socket接口免编码:完全封装HTTP以及Socket接口,协议模板+纯关键字驱动,免编码,初级测试人员的福音,与其他类似开源工具相比优势明显11、在线调试用例:用例步骤管理界面直接调试自动化用例,避免使用...

    socket-starter:socket.io 2 + Express 4 + Node.js集群+ MongoDB Sticky-Session

    常见用例 单进程应用服务器,例如免费的heroku.com帐户或类似的服务器 建立聊天 制作节点+ JavaScript游戏 安装 它作为npm软件包托管,因此安装当然很简单: yarn add socket-starter --save # you will also need ...

    C#WebSocket示例(初学者必备)

    C# WebSocket 服务端和网页端示例,初学者必备!

    2019RaspberryPi项目:Phoenix-Linux-SocketCAN-示例

    Phoenix-Linux-SocketCAN-示例在Linux / RaspPi平台上使用CTRE Phoenix类库的一般示例。 演示了两个用例... 对于非FRC用例(将无线游戏手柄插入Raspberry PI中),运行没有roboRIO的机器人。 在FRC竞赛中使用roboRIO...

    random-lodash-mixins:缺少 Lodash 的某些功能,但在使用例如 AngularJS + Socket.io 时可能很有用

    除了简单的例子,还有一些特别好的使用 AngularJS + Socket.io 的用例。 数组操作 我删除了这些函数,因为 Lo-Dash 已经提供了并且可以使用原生 JS 和 Lo-Dash 完成附加和前置。 下面是使用 Array.unshift 和 push...

    BrowserJumper:BrowserJumper - 下一个版本的游戏。 这个带有 js 和 tomcat 8 的 web socket

    这个带有 js 和 tomcat 8 的 web socket。 websockets的优势: WebSockets 的效率、简单性和更少的带宽 WebSockets 比轮询等其他解决方法更高效、更高效。 它们需要更少的带宽并减少延迟。 WebSockets 简化了实时...

    阻塞与非阻塞

    最近帮一哥们做一个简单的通信演示小程序,重拾遗忘很久的Windows网络编程,通过此次演示程序的制作,对于TCP的三路握手、Socket的运用理解更加深入了,同时从文字上的阻塞与非阻塞到情真意切的感受到二者之间的差异...

    rxjs-websockets:一个非常灵活,简单的rxjs websocket库

    observable-socket为用户提供输入主题,rxjs-websockets允许用户提供输入流作为参数,以允许用户选择具有适合其自身用例的语义的observable(可以使用实现与observable-socket相同的语义)。 使用observable-socket...

    spider-website:在网站上显示 URL 的简单蜘蛛

    蜘蛛网站一个简单的爬虫应用程序,它使用 Socket.io 抓取提交的网站并更新结果去做: 添加测试用例使用引导程序添加样式更改为在 Socket.io 中使用 Angular JS 功能:爬虫跟踪外部 URL 功能:图像和文件预览(或缩略...

    easy-socket:现代C ++ 11本机,与操作系统无关的套接字库,以单个标头开头,包括

    轻轻松松具有单个标头的现代C ++ 11本机,与操作系统无关的套接字库/启动程序代码包括特征简易:通过包含单个头文件开始使用简单的套接字功能可移植:在Windows和Linux上均可使用可配置:可以轻松地从头文件访问和...

    LuckyFrame测试平台-其他

    2、专业用例管理:自动化用例的专业管理方式,让您编写自动化用例更简单,直观。 3、质量管理:Web端不仅仅有用来管理自动化相关的模块,更可以做一些简单的质量数据收集分析以及数据的多图表展示。 4、多线程执行...

Global site tag (gtag.js) - Google Analytics