C#套接字服务器和HTML/javascript套接字客户端
本文关键字:套接字 javascript 客户端 服务器 HTML | 更新日期: 2023-09-27 18:26:16
我正在客户端(html页面和javascript)和服务器(C#控制台应用程序)之间建立连接。目标是拥有一个聊天界面。
我对下面的代码有两个问题:
- 当用户键入消息时,它只向服务器发送第一条消息
- 当我显示发送给其他用户的消息时,它带有奇怪的字符,如
��n~Z� (�B�(@
我的代码如下:
public static ManualResetEvent allDone = new ManualResetEvent(false);
static void Main(string[] args)
{
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
server.Bind(new IPEndPoint(IPAddress.Any, 8080));
server.Listen(128);
while (true)
{
allDone.Reset();
Console.WriteLine("Waiting for a connection...");
server.BeginAccept(new AsyncCallback(callback_BeginAccept), server);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
private static void callback_BeginAccept(IAsyncResult result)
{
allDone.Set();
Socket listener = (Socket)result.AsyncState;
Socket handler = listener.EndAccept(result);
byte[] buffer = new byte[1024];
var i = handler.Receive(buffer);
string headers = (Encoding.UTF8.GetString(buffer)).Substring(0, i);
Console.WriteLine("------------------------------------");
Console.WriteLine("--------- CLIENT HEADERS ----------");
Console.WriteLine("------------------------------------");
Console.WriteLine(headers);
// Handles the handshake -> this is working
handshake(handler, result, headers);
listOfPeopleInChat.Add(handler);
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(callback_BeginReceive), state);
}
public static void callback_BeginReceive(IAsyncResult ar)
{
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead));
string content = state.sb.ToString();
Console.WriteLine("Read {0} bytes from socket. 'n Data : {1}", content.Length, content);
foreach (Socket i in listOfPeopleInChat)
sendMessage(content, i); // This works only for the first message typed in
}
}
编辑1:我处理WebSockets请求的javascript代码:
var socket = new WebSocket("http://localhost:8080");
socket.onopen = function(){
message('<p class="event">Socket Status: '+socket.readyState+' (open)');
}
socket.onmessage = function(msg){
message('<p class="message">Received: '+msg.data);
}
socket.onclose = function(){
message('<p class="event">Socket Status: '+socket.readyState+' (Closed)');
}
$(document).on('click', '#send', function()
{
socket.send($('#msg').val());
});
EDIT 2:sendMessage()函数如下:
private static void sendMessage(String mess, Socket client)
{
byte[] rawData = Encoding.UTF8.GetBytes(mess);
int frameCount = 0;
byte[] frame = new byte[10];
frame[0] = (byte) 129;
if(rawData.Length <= 125){
frame[1] = (byte) rawData.Length;
frameCount = 2;
}
else if (rawData.Length >= 126 && rawData.Length <= 65535)
{
frame[1] = (byte) 126;
int len = rawData.Length;
frame[2] = (byte)((len >> 8 ) & (byte)255);
frame[3] = (byte)(len & (byte)255);
frameCount = 4;
}else{
frame[1] = (byte) 127;
int len = rawData.Length;
frame[2] = (byte)((len >> 56 ) & (byte)255);
frame[3] = (byte)((len >> 48 ) & (byte)255);
frame[4] = (byte)((len >> 40 ) & (byte)255);
frame[5] = (byte)((len >> 32 ) & (byte)255);
frame[6] = (byte)((len >> 24 ) & (byte)255);
frame[7] = (byte)((len >> 16 ) & (byte)255);
frame[8] = (byte)((len >> 8 ) & (byte)255);
frame[9] = (byte)(len & (byte)255);
frameCount = 10;
}
int bLength = frameCount + rawData.Length;
byte[] reply = new byte[bLength];
int bLim = 0;
for(int i=0; i<frameCount;i++){
reply[bLim] = frame[i];
bLim++;
}
for(int i=0; i<rawData.Length;i++){
reply[bLim] = rawData[i];
bLim++;
}
client.Send(reply);
}
在服务器代码中,每个连接只尝试接收一次数据。
同样基于您的代码,如果任何消息大于缓冲区大小,您将只得到部分消息。
在接收回调中,您需要再次调用BeginReceive,以便可以接收另一条消息(或消息的其余部分)。