小弟初接触网络通信相关,学习了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;
        }WebSocketC#网络通信数据

解决方案 »

  1.   

    1、因为需要一个数据头(最少2个字节),该数据头包含传输数据的各种信息。比如类型(OpCode),长度,是否结束(Fin)等。为了节省传输,如果长度很小,就直接放进2个字节的数据头,如果长度比较大,就把具体长度写在2个字节的后面。
    如果长度事先不知道,就用Fin标志来标注最后一个数据包...2、在进入WebSocket模式之前,客户和服务器用的是HTTP协议,客户和服务器只能理解HTTP内容。现在,要利用现有的TCP连接,进入WebSocket模式,双方就要进行一次HTTP协商,该协商就是HTTP请求握手。3、不可以。