读书人

WebSocket的相干难题

发布时间: 2013-09-07 14:12:45 作者: rapoo

WebSocket的相关难题
小弟初接触网络通信相关,学习了WebSocket的C#服务端,有些疑问还请前辈们赐教。谢谢了!
1.下面的代码是服务端将内容发向客户端的,不明白为什么要这样组织(尤其是中间那判断长度的处理),直接Encoding.UTF8.GetBytes(str)为什么不行?
2.从示例中理解,服务端的Socket接受到客户端的连接,然后读取第一个请求内容,做HTTP内容解析,内容符合后,返回一个HTTP文字内容,这期间都是TcpSocket直接的连接,然后内容传输,那HTTP内容那段感觉多余样的,而我看了一些WebSocket的文章好像是说先HTTP请求握手,然后TCP连接,既然HTML5能进行TCP连接,为什么会多出那么一个HTTP请求握手呢?
3.看到一些文章说TCP连接,是可靠的,如果数据到达接收端,不完整或乱序,会让发送端重发,但这样就阻碍了下面信息的发送,能否有什么方法取消这种可靠呢?让数据包允许丢失呢?(UDP的话就好像跳出WebSocket的范围了)


public static byte[] GetBytesByStr(string str) {
byte[] dataBytes = Encoding.UTF8.GetBytes(str);
int length = dataBytes.Length;

byte[] extendBytes;
byte[] headBytes;
if (length < 126) {
extendBytes = new byte[0];
headBytes = GetHeadBytes(true, false, false, false, OpCode.Text, false, length);
} else if (length < 65536) {
extendBytes = new byte[2];
headBytes = GetHeadBytes(true, false, false, false, OpCode.Text, false, 126);
extendBytes[0] = (byte)(length / 256);
extendBytes[1] = (byte)(length % 256);
} else {
extendBytes = new byte[8];
headBytes = GetHeadBytes(true, false, false, false, OpCode.Text, false, 127);
int left = length;
int unit = 256;


for (int i = 7; i > 1; i--) {
extendBytes[i] = (byte)(left % unit);
left = left / unit;
if (left == 0) { break; }
}
}

byte[] maskBytes = new byte[0];

byte[] buffer = new byte[2 + extendBytes.Length + maskBytes.Length + dataBytes.Length];
Buffer.BlockCopy(headBytes, 0, buffer, 0, 2);
Buffer.BlockCopy(extendBytes, 0, buffer, 2, extendBytes.Length);
Buffer.BlockCopy(maskBytes, 0, buffer, 2 + extendBytes.Length, maskBytes.Length);
Buffer.BlockCopy(dataBytes, 0, buffer, 2 + extendBytes.Length + maskBytes.Length, dataBytes.Length);
return buffer;
}

private static byte[] GetHeadBytes(bool fin, bool rsv1, bool rsv2, bool rsv3, OpCode opcode, bool hasmask, int length) {
byte[] buffer = new byte[2] { 0, 0 };
if (fin) { buffer[0] ^= 0x80; }
if (rsv1) { buffer[0] ^= 0x40; }
if (rsv2) { buffer[0] ^= 0x20; }
if (rsv3) { buffer[0] ^= 0x10; }


buffer[0] ^= (byte)opcode;
if (hasmask) { buffer[1] ^= 0x80; }
buffer[1] ^= (byte)((sbyte)length);
return buffer;
}

WebSocket C# 网络 通信 数据
[解决办法]
这是把数据打包。

不打包的话,接收方不知道数据有多少,也分不清是这次数据还是下次数据。

[解决办法]
1、因为需要一个数据头(最少2个字节),该数据头包含传输数据的各种信息。比如类型(OpCode),长度,是否结束(Fin)等。为了节省传输,如果长度很小,就直接放进2个字节的数据头,如果长度比较大,就把具体长度写在2个字节的后面。
如果长度事先不知道,就用Fin标志来标注最后一个数据包...

2、在进入WebSocket模式之前,客户和服务器用的是HTTP协议,客户和服务器只能理解HTTP内容。现在,要利用现有的TCP连接,进入WebSocket模式,双方就要进行一次HTTP协商,该协商就是HTTP请求握手。

3、不可以。

读书人网 >C#

热点推荐