【WebSocket No.1】实现服务端webSocket连接通讯
前言
现阶段socket通信使用TCP、UDP协议,其中TCP协议相对来说比较安全稳定!本文也是来讲解TCP为主(恕在下学艺不精)。
下面是个人理解的tcp/ip进行通讯之间的三次握手!
1.客户端先发送报文到服务端
2.服务端接受到报文之后进行回复
3.客户端收到回复之后再次发送确认信息。这个时候才是正式进行连接。
什么是WebSocket
WebSocket 是一种网络通信协议。RFC6455 定义了它的通信标准。
WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
与传统的HTTP协议对比:
HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。也就是说HTTP没有办法做到在客户端不请求服务器的情况下主动给客户端发送消息。但是这种情况有时确实我们必须的。当然我们在WebSocket之前我们也是有办法解决的,比如我们使用轮询技术来实现一部分的目的,但是有了WebSocket是必轮询更加合理的解决方案。
WebSocket API介绍
创建WebSocket 对象,这是所有步骤的第一步。
var Socket = new WebSocket(url, [protocol] );
WebSocket 对象属性
Socket.readyState:只读属性 readyState 表示连接状态,可以是以下值:0 - 表示连接尚未建立。1 - 表示连接已建立,可以进行通信。2 - 表示连接正在进行关闭。3 - 表示连接已经关闭或者连接不能打开。
Socket.bufferedAmount:只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。
WebSocket 事件
WebSocket 存在基本的的四个事件处理
Socket.onopen:连接建立时触发
Socket.onmessage:客户端接受到服务器发送的消息时候触发
Socket.onerror:通许期间发生错误时触发
Socket.onclose:连接关闭触发,不管你主动还是被动的
WebSocket 方法
Socket.send():发送消息给服务器
Socket.close():关闭连接,客户端主动关闭。
连接形式:
服务器监听:服务器开启服务之后,就进入了监听客户端连接状态。此时不是指定监听那台客户端那是处于一个等待状态(不是暂停,一直处于网络实时监听),等待客户端找他进行连接。
客户端连接:客户端对目标服务器发起链接请求,发起请求必须要知道IP以及相应端口号。
确认链接:这个时候服务端的监听就起作用了,受到客户端的请求后会响应客户端请求,创建socket链接。在这里需要注意链接不是一对一的,服务端会重新对请求客户端创建新的socket服务。所以服务端仍处于监听状态仍可以监听。
代码示例
好了以上就是一些基本介绍,主要是为了以下的东西做铺垫,毕竟要实现需要有socket的基础,言归正传。下面开始我们完整的webSocket练习吧!(网上有些使用插件或者类库实现的websocket。但是我们所讲的是以socket为基础的)
创建服务器
别的不多少首先创建socket服务器:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Text.RegularExpressions;
using System.Security.Cryptography; namespace SocketService
{
class SocketService
{
private static byte[] result = new byte[];
private static int myProt = ; //端口
static Socket serverSocket; //服务器服务
public void Start()
{
//服务器IP地址
IPAddress ip = IPAddress.Parse("127.0.0.1");
//socket的构造函数进行服务注册
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//绑定IP地址:端口
serverSocket.Bind(new IPEndPoint(ip, myProt));
//设定最多10个排队连接请求
serverSocket.Listen();
Console.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString());
//通过Clientsoket发送数据
Thread myThread = new Thread(ListenClientConnect);
myThread.Start();
Console.ReadLine();
}
/// <summary>
/// 监听客户端连接
/// </summary>
private void ListenClientConnect()
{
while (true)
{
Socket clientSocket = serverSocket.Accept();
// clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello"));
Thread receiveThread = new Thread(ReceiveMessage);
receiveThread.Start(clientSocket);
}
} /// <summary>
/// 接收消息
/// </summary>
/// <param name="clientSocket"></param>
private void ReceiveMessage(object clientSocket)
{
Socket myClientSocket = (Socket)clientSocket;
while (true)
{
try
{
//通过clientSocket接收数据
int receiveNumber = myClientSocket.Receive(result);
// websocket建立连接的时候,除了TCP连接的三次握手,websocket协议中客户端与服务器想建立连接需要一次额外的握手动作
string msg = Encoding.UTF8.GetString(result, , receiveNumber);
var buffer = result;
if (msg.Contains("Sec-WebSocket-Key"))
{ myClientSocket.Send(PackageHandShakeData(buffer, receiveNumber)); // return;
}
var ss = AnalyzeClientData(result, receiveNumber);
Console.WriteLine("接收客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.UTF8.GetString(result, , receiveNumber));
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
myClientSocket.Shutdown(SocketShutdown.Both);
myClientSocket.Close();
break;
}
}
}
}
}
代码注释我已经写的很详细了!希望你们能看懂(哈哈)!
看到这里有些聪明的网友可能发现问题了!或者操作过但是没有成功的也看出了不同。没有错,在这里我要说明的一点是有些websocket与socket有点不同的就是他的握手的首次信息以及返回信息是需要特定格式的。
也就是所谓的响应头域需要特殊处理。在不做相对应的响应处理浏览器会报“握手不成功”的错误!
参考网址:http://www.cnblogs.com/smark/archive/2012/11/26/2789812.html
如果初步同学没有看明白请移至另一篇博客,详细封装了此方法解决此错误。(方便有些同学查找错误找不到解决方法,因为鄙人也是搞了一上午才有幸发现此问题,还望海涵)
最后我们只需要在主方法进行调用开启服务

此时服务端代码大功告成!下面我们使用js来进行请求就可以了。
客户端
下面附送html建议代码也可以去w3c查看教程:
html代码:
<body>
<a href="javascript:WebSocketTest()">运行 WebSocket</a>
<a href="javascript:webSocketClose()">关闭WebSocket</a>
<div id="look" class="m"> </div>
<input id="message">
<a href="javascript:send()">发送消息</a>
</body>
javascript代码:
var ws;
function WebSocketTest() {
if("WebSocket" in window) {
alert("您的浏览器支持 WebSocket!");
// 打开一个 web socket
ws = new WebSocket("ws://127.0.0.1:8885");
ws.onopen = function() {
// Web Socket 已连接上,使用 send() 方法发送数据
ws.send("发送数据");
alert("数据发送中...");
};
ws.onmessage = function(evt) {
var received_msg = evt.data;
document.getElementById("look").html+=received_msg;
alert("数据已接收...");
};
ws.onclose = function() {
// 关闭 websocket
alert("连接已关闭...");
};
} else {
// 浏览器不支持 WebSocket
alert("您的浏览器不支持 WebSocket!");
}
}
function webSocketClose() {
ws.close();
alert("关闭了通讯")
}
function send(){
var msg= document.getElementById("message").value;
if(msg==""||msg==undefined){
alert("请填写发送内容!")
return;
}
ws.send("1111111111");
alert("发送了消息")
}
最后附上运行截图:


好了以上就是webSocket的一些基础介绍和简单的代码示例。
下一篇在此基础上完善成一个聊天示例:【WebSocket No.2】WebSocket和Socket实现聊天群发
【WebSocket No.1】实现服务端webSocket连接通讯的更多相关文章
- Unable to unwrap data, invalid status [CLOSED]-服务端webSocket报错
一.问题由来 现在的项目中在使用webSocket这门技术,主要用来在服务端和客户端进行实时的数据传输,因为需要及时的进行响应,所以才没有使用http请求的方式, 而是使用socket的方式,这样可以 ...
- Kafka技术内幕 读书笔记之(二) 生产者——服务端网络连接
KafkaServer是Kafka服务端的主类, KafkaServer中和网络层有关的服务组件包括 SocketServer.KafkaApis 和 KafkaRequestHandlerPool后 ...
- 6-1 建立客户端与zk服务端的连接
6-1 建立客户端与zk服务端的连接 zookeeper原生java api使用 会话连接与恢复; 节点的增删改查; watch与acl的相关操作; 导入jar包;
- NIO 服务端TCP连接管理的方案
最近做的一个项目需要在服务端对连接端进行管理,故将方案记录于此. 方案实现的结果与背景 因为服务端与客户端实现的是长连接,所以需要对客户端的连接情况进行监控,防止无效连接占用资源. 完成类似于心跳的接 ...
- 客户端 new socket时候 就像服务端发起连接了
客户端 new socket时候 就像服务端发起连接了
- 经典!服务端 TCP 连接的 TIME_WAIT 过多问题的分析与解决
开源Linux 专注分享开源技术知识 本文给出一个 TIME_WAIT 状态的 TCP 连接过多的问题的解决思路,非常典型,大家可以好好看看,以后遇到这个问题就不会束手无策了. 问题描述 模拟高并发的 ...
- 基于socket.io客户端与服务端的相互通讯
socket.io是对websocket的封装,用于客户端与服务端的相互通讯.官网:https://socket.io/. 下面是socket.io的用法: 1.由于使用express开的本地服务,先 ...
- c#实现服务端webSocket
现阶段socket通信使用TCP.UDP协议,其中TCP协议相对来说比较安全稳定!本文也是来讲解TCP为主(恕在下学艺不精). 下面是个人理解的tcp/ip进行通讯之间的三次握手! 1.客户端先发送报 ...
- 利用WebSocket和EventSource实现服务端推送
可能有很多的同学有用 setInterval 控制 ajax 不断向服务端请求最新数据的经历(轮询)看下面的代码: setInterval(function() { $.get('/get/data- ...
随机推荐
- [solution] JZOJ 5459. 密室
[solution] JZOJ 5459. 密室 Description 小X 正困在一个密室里,他希望尽快逃出密室. 密室中有$N$ 个房间,初始时,小X 在1 号房间,而出口在N 号房间. 密室的 ...
- java安全与加解密
1 安全 安全性相关内容分为认证.授权和审计(发现安全问题时可以查看相关历史记录) 用户认证 java API表示主体的是javax.security.auth.Subject类型,表示用户身份标识的 ...
- 瞎搞poj1008
http://poj.org/problem?id=1008 题意: 两种历法: 1.Haab,一年365天,共19个月,前18月有20天(编号为0-19),最后一个月有5天(编号为0-4)pop(1 ...
- WeexSDK源码分析(iOS)
0.从工作原理谈起 Weex 表面上是一个客户端技术,但实际上它串联起了从本地开发.云端部署到分发的整个链路.开发者首先可在本地像编写 web 页面一样编写一个 app 的界面,然后通过命令行工具将之 ...
- ReactNative学习笔记(一)环境搭建
前言 本文开发环境为Windows,目标平台为Android,react-native版本为0.35.0. 环境搭建 注意,本文不是按照官网的教程来的,官网说必须安装什么Chocolatey,我懒得鸟 ...
- springboot之使用redistemplate优雅地操作redis
概述 本文内容主要 关于spring-redis 关于redis的key设计 redis的基本数据结构 介绍redis与springboot的整合 sringboot中的redistemplate的使 ...
- 第十节:详细讲解一下Java多线程,随机文件
前言 大家好,给大家带来第十节:详细讲解一下Java多线程,随机文件的概述,希望你们喜欢 多线程的概念 线程的生命周期 多线程程序的设计 多线程的概念 多线程的概念:程序是静态的,进程是动态的.多进程 ...
- PHP利用Session实现上传进度
实现文件上传进度条基本是依靠JS插件或HTML5的File API来完成,其实PHP配合ajax也能实现此功能. PHP手册对于session上传进度是这么介绍的: 当 session.upload_ ...
- centos7配置apache服务
首先写下基本的步骤: 1.环境准备:关闭防火墙(不关闭无法访问,我这里只是简单的配置,实际部署项目应该会有具体的设置),关闭selinux(试过,不关闭也没事,一般都关闭) 配置 ip 2.安装软件包 ...
- Liferay7 BPM门户开发之25: Liferay7应用程序配置(APPLICATION CONFIGURATION)
首先有几个概念需要明确.1.第一个概念是这里的应用程序配置不是写XML之类的配置文件,是类似字典的类型化配置这意味着应用程序配置不只是一个字符串键值对的列表.值还可以有类型,如整数列表,字符串列表,一 ...