c#实现服务端webSocket
现阶段socket通信使用TCP、UDP协议,其中TCP协议相对来说比较安全稳定!本文也是来讲解TCP为主(恕在下学艺不精)。
下面是个人理解的tcp/ip进行通讯之间的三次握手!
1.客户端先发送报文到服务端
2.服务端接受到报文之后进行回复
3.客户端收到回复之后再次发送确认信息。这个时候才是正式进行连接。
首先说一下连接形式:
服务器监听:服务器开启服务之后,就进入了监听客户端连接状态。此时不是指定监听那台客户端那是处于一个等待状态(不是暂停,一直处于网络实时监听),等待客户端找他进行连接。
客户端连接:客户端对目标服务器发起链接请求,发起请求必须要知道IP以及相应端口号。
确认链接:这个时候服务端的监听就起作用了,受到客户端的请求后会响应客户端请求,创建socket链接。在这里需要注意链接不是一对一的,服务端会重新对请求客户端创建新的socket服务。所以服务端仍处于监听状态仍可以监听。
好了以上就是一些基本介绍,主要是为了一下的东西做铺垫,毕竟要实现需要有socket的基础,言归正传。下面开始我们完整的webSocket练习吧!(网上有些使用插件或者类库实现的websocket。但是我们所讲的是以socket为基础的)
别的不多少首先创建socket服务器:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Net.Sockets; 7 using System.Net; 8 using System.Threading; 9 using System.Text.RegularExpressions; 10 using System.Security.Cryptography; 11 12 namespace SocketService 13 { 14 class SocketService 15 { 16 private static byte[] result = new byte[1024]; 17 private static int myProt = 8885; //端口 18 static Socket serverSocket; //服务器服务 19 public void Start() 20 { 21 //服务器IP地址 22 IPAddress ip = IPAddress.Parse("127.0.0.1"); 23 //socket的构造函数进行服务注册 24 serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 25 //绑定IP地址:端口 26 serverSocket.Bind(new IPEndPoint(ip, myProt)); 27 //设定最多10个排队连接请求 28 serverSocket.Listen(10); 29 Console.WriteLine("启动监听{0}成功", serverSocket.LocalEndPoint.ToString()); 30 //通过Clientsoket发送数据 31 Thread myThread = new Thread(ListenClientConnect); 32 myThread.Start(); 33 Console.ReadLine(); 34 } 35 /// <summary> 36 /// 监听客户端连接 37 /// </summary> 38 private void ListenClientConnect() 39 { 40 while (true) 41 { 42 Socket clientSocket = serverSocket.Accept(); 43 // clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello")); 44 Thread receiveThread = new Thread(ReceiveMessage); 45 receiveThread.Start(clientSocket); 46 } 47 } 48 49 /// <summary> 50 /// 接收消息 51 /// </summary> 52 /// <param name="clientSocket"></param> 53 private void ReceiveMessage(object clientSocket) 54 { 55 Socket myClientSocket = (Socket)clientSocket; 56 while (true) 57 { 58 try 59 { 60 //通过clientSocket接收数据 61 int receiveNumber = myClientSocket.Receive(result); 62 // websocket建立连接的时候,除了TCP连接的三次握手,websocket协议中客户端与服务器想建立连接需要一次额外的握手动作 63 string msg = Encoding.UTF8.GetString(result, 0, receiveNumber); 64 var buffer = result; 65 if (msg.Contains("Sec-WebSocket-Key")) 66 { 67 68 myClientSocket.Send(PackageHandShakeData(buffer, receiveNumber)); 69 70 // return; 71 } 72 var ss = AnalyzeClientData(result, receiveNumber); 73 Console.WriteLine("接收客户端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.UTF8.GetString(result, 0, receiveNumber)); 74 } 75 catch (Exception ex) 76 { 77 Console.WriteLine(ex.Message); 78 myClientSocket.Shutdown(SocketShutdown.Both); 79 myClientSocket.Close(); 80 break; 81 } 82 } 83 } 84 } 85 }
代码注释我已经写的很详细了!希望你们能看懂(哈哈)!
看到这里有些聪明的网友可能发现问题了!或者操作过但是没有成功的也看出了不同。没有错,在这里我要说明的一点是有些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("发送了消息") }
最后附上运行截图: