我完全不熟悉WebSocket编程,我尝试使用WebSocket在两个本机应用程序之间建立通信,我的服务器程序基于VB.net,而我的客户端程序基于C#。 我可以建立连接并进行握手,但是当我尝试发送数据时,仅在客户端接收到第一个数据,然后我收到错误消息:“远程方在未完成关闭握手的情况下关闭了WebSocket连接。”
有人可以帮助解决这个问题吗?
服务器:
模块程序
Dim serverTcp As TcpListener
Dim serverThread As Thread
Dim host_ As String = "127.0.0.1"
Dim curSocket As Socket
Sub Main(args As String())
'serverThread = New Thread(AddressOf serverProc)
'serverThread.Start()
serverProc()
End Sub
Private Sub serverProc()
Try
'' Listen to port 8000
serverTcp = New TcpListener(IPAddress.Loopback, 8087)
serverTcp.Start()
Console.WriteLine("Listen to port 8000 ...")
'' Accept any connection
While (True)
curSocket = serverTcp.AcceptSocket()
clientProc(curSocket)
'serverTcp.Stop()
End While
Catch ex As Exception
End Try
End Sub
Private Sub clientProc(ByVal sck As Socket)
Try
Dim netStream As New NetworkStream(sck)
Dim netReader As New IO.StreamReader(netStream)
Dim netWriter As New IO.StreamWriter(netStream)
Dim key As String = ""
Console.WriteLine("Accept new connection ...")
'' Reading handshake message
While (True)
Dim line As String = netReader.ReadLine()
If line.Length = 0 Then
Exit While
End If
If (line.StartsWith("Sec-WebSocket-Key: ")) Then
key = line.Split(":")(1).Trim()
End If
Console.WriteLine("Data: " & line)
End While
'' Calculate accept-key
key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
key = getSHA1Hash(key)
'' Response handshake message
Dim response As String
'Console.WriteLine("Response....")
response = "HTTP/1.1 101 Switching Protocols" & vbCrLf
response &= "Upgrade: websocket" & vbCrLf
response &= "Connection: Upgrade" & vbCrLf
response &= "Sec-WebSocket-Accept: " & key & vbCrLf & vbCrLf
netWriter.Write(response)
netWriter.Flush()
'' Sending message
'Dim message As String = "Hello World"
'Dim messageByte() As Byte = System.Text.Encoding.UTF8.GetBytes(message)
''Dim messageByte() As Byte = System.Text.Encoding.UTF8.GetBytes(message)
'Dim startByte() As Byte = {&H0}
'Dim endByte() As Byte = {&HFF}
'sck.Send(startByte, 1, 0)
'sck.Send(messageByte)
'sck.Send(endByte, 1, 0)
'ReceiveMessage(sck)
Dim a As Integer = 1
While a < 100
'Message(sck, "hello")
SendMessage(sck, a.ToString())
'ReceiveMessage(sck)
'SendMessage(sck, "hello")
'serverTcp.Stop()
a = a + 1
Thread.Sleep(1000)
End While
'serverTcp.Stop()
Catch ex As Exception
End Try
End Sub
Sub Msg(t As String)
Console.WriteLine(t)
End Sub
Function getSHA1Hash(ByVal strToHash As String) As String
Dim sha1Obj As New System.Security.Cryptography.SHA1CryptoServiceProvider
Dim bytesToHash() As Byte = System.Text.Encoding.ASCII.GetBytes(strToHash)
Dim result As String
bytesToHash = sha1Obj.ComputeHash(bytesToHash)
result = Convert.ToBase64String(bytesToHash)
Console.WriteLine(result)
Return result
End Function
Sub SendMessage(sck As Socket, message As String)
'Dim reply1 As String = ""
'message = message.Split(":")(1).Trim()
Console.Write(message.GetType())
Dim rawData = System.Text.Encoding.UTF8.GetBytes(message)
Console.Write(rawData.Length)
Dim frameCount = 0
Dim frame(10) As Byte
frame(0) = CByte(129)
'Console.WriteLine(rawData.Length)
If rawData.Length <= 125 Then
frame(1) = CByte(rawData.Length)
frameCount = 2
ElseIf rawData.Length >= 126 AndAlso rawData.Length <= 65535 Then
frame(1) = CByte(126)
Dim len = CByte(rawData.Length)
frame(2) = CByte(((len >> 8) & CByte(255)))
frame(3) = CByte((len & CByte(255)))
frameCount = 4
Else
frame(1) = CByte(127)
Dim len = CByte(rawData.Length)
frame(2) = CByte(((len >> 56) & CByte(255)))
frame(3) = CByte(((len >> 48) & CByte(255)))
frame(4) = CByte(((len >> 40) & CByte(255)))
frame(5) = CByte(((len >> 32) & CByte(255)))
frame(6) = CByte(((len >> 24) & CByte(255)))
frame(7) = CByte(((len >> 16) & CByte(255)))
frame(8) = CByte(((len >> 8) & CByte(255)))
frame(9) = CByte((len & CByte(255)))
frameCount = 10
End If
Dim bLength = frameCount + rawData.Length
Console.WriteLine(rawData.Length)
'Console.WriteLine(frameCount)
'Console.WriteLine(rawData.Length)
'Dim leng = 4
Dim reply(bLength + 1) As Byte
Dim bLim = 0
For i = 0 To frameCount - 1
'Console.WriteLine(bLim)
'Console.WriteLine(reply(bLim))
reply(bLim) = frame(i)
'Console.WriteLine(reply(bLim))
bLim += 1
Next
For i = 0 To rawData.Length - 1
'Console.WriteLine(bLim)
reply(bLim) = rawData(i)
bLim += 1
Next
'For i = 0 To reply.Length
'Console.WriteLine(reply(i))
'Next
sck.Send(reply)
End Sub
最终模块
客户:
class Program
{
static async Task Main(string[] args)
{
do
{
// var socket = new ClientWebSocket();
using (var socket = new ClientWebSocket())
try
{
await socket.ConnectAsync(new Uri("ws://localhost:8087"), new System.Threading.CancellationToken());
await Send(socket, "hello");
await Receive(socket);
await socket.CloseAsync(WebSocketCloseStatus.NormalClosure, "", new System.Threading.CancellationToken());
}
catch (Exception ex)
{
Console.WriteLine($"ERROR - {ex.Message}");
}
} while (true);
}
private static void WebSocketState(ClientWebSocket socket)
{
throw new NotImplementedException();
}
static async Task Send(ClientWebSocket socket, string data)
{
await socket.SendAsync(Encoding.UTF8.GetBytes(data), WebSocketMessageType.Text, true, new System.Threading.CancellationToken());
}
static async Task Receive(ClientWebSocket socket)
{
var buffer = new ArraySegment<byte>(new byte[8192]);
do
{
WebSocketReceiveResult result = null;
using (var ms = new System.IO.MemoryStream())
{
do
{
result = await socket.ReceiveAsync(buffer, new System.Threading.CancellationToken());
ms.Write(buffer.Array, buffer.Offset, result.Count);
} while (!result.EndOfMessage);
if (result.MessageType == WebSocketMessageType.Close)
break;
ms.Seek(0, new System.IO.SeekOrigin());
using (var reader = new System.IO.StreamReader(ms, Encoding.UTF8))
Console.WriteLine(await reader.ReadToEndAsync());
}
} while (true);
}
}
}