0

I'm making a connection between the client (html page & javascript) and server (C# console app). The goal is to have a chat interface.

I have two problems with the code below:

  1. When the user types a message it only sends the first one to the server
  2. When I show the message sent to the other users it comes with strange characters like ��n~Z� (�B�(@

And my code is the following:

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
    }
}

EDIT 1: My javascript code for handling the requests of WebSockets:

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: The sendMessage() function is the following:

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);
}
Linesofcode
  • 5,327
  • 13
  • 62
  • 116
  • Are you trying to use WebSockets? How is the JavaScript communicating with the socket? You're not showing any JavaScript code. – dmeglio Dec 09 '15 at 14:07
  • I didn't showed because it's the default code for WebSockets, yes. I'll edit my question. – Linesofcode Dec 09 '15 at 14:08
  • Then I'm confused as your code isn't using the WebSockets protocol at all from what I can see. – dmeglio Dec 09 '15 at 14:11
  • @dman2306 please see my updated topic. – Linesofcode Dec 09 '15 at 14:12
  • 1
    I see the update, but I'm seeing a regular old socket, not anything implementing the WebSocket protocol. I don't see you decoding the bytes, have a look at https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_server specifically the Decoding Algorithm. – dmeglio Dec 09 '15 at 14:14
  • I'm implementing something like this http://stackoverflow.com/questions/10200910/create-hello-world-websocket-example, as you can see by matching my code with it. – Linesofcode Dec 09 '15 at 14:45
  • Your code doesn't match that because that code is sending the HTTP headers necessary to implement WebSockets. Is that what `handshake()` does? You didn't include it. Also, if `sendMessage` is the method that "only works once" why aren't you sharing the code for that method? It sounds like it might be the source of the problems. – dmeglio Dec 09 '15 at 14:48
  • Ahhh, I didn't put the `handshake()` because it is alot of code with more two or three functions. But yes, is what `handshake()` does and it is correct. The `sendMessage` is where the problem is for my second problem, yes. But my main issue is not being able to send more than one message..I mean I send the messages but only the first one reaches the server. I thought this might be due to my `while(true)`? – Linesofcode Dec 09 '15 at 14:54
  • @dman2306 The issue with the characters probably is due to the function `sendMessage()` - I have updated the topic - but my biggest issue is the other I told you. – Linesofcode Dec 09 '15 at 14:57

1 Answers1

1

In your server code each connection only attempts to receive data once.

Also based on your code, if any message is greater than the buffer size - you would only get a partial message.

In your receive callback, you need to call BeginReceive again so that another message (or the rest of the message) can be received.

Chris
  • 1,118
  • 8
  • 24