1

i have this c# class

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Security.Cryptography;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

class Server
{
  const string SERVER_IP = "127.0.0.1";
  const int  SERVER_PORT = 9998;
   TcpListener server = new TcpListener(IPAddress.Parse(SERVER_IP), SERVER_PORT);
  public void Start ()
  {
    server.Start();
    Console.WriteLine("Server has started on "+SERVER_IP+":"+SERVER_PORT+".{0}Waiting for a connection...", Environment.NewLine);
    TcpClient client;
    while (true) // Add your exit flag here
    {
        client = server.AcceptTcpClient();
        Socket Socket = new Socket(SocketType.Stream, ProtocolType.Tcp);

        ThreadPool.QueueUserWorkItem(ThreadProc, client);
    }
 }

private void ThreadProc(object obj)
{
    Console.WriteLine("A client connected.");
    TcpClient client = (TcpClient)obj;
    NetworkStream stream = client.GetStream();

    int UnactiveTimePeriod = int.Parse(TimeSpan.FromMinutes(1).TotalMilliseconds.ToString());
    //enter to an infinite cycle to be able to handle every change in stream
    while (true)
    {

        while (!stream.DataAvailable) ;

        Byte[] bytes = new Byte[client.Available];

        stream.Read(bytes, 0, bytes.Length);
        // translate bytes of request to string
        string data = Encoding.UTF8.GetString(bytes);

        if (new Regex("^GET").IsMatch(data)) // Handshaking protocol
        {
            Byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + Environment.NewLine
                + "Connection: Upgrade" + Environment.NewLine
                + "Upgrade: websocket" + Environment.NewLine
                + "Sec-WebSocket-Accept: " + Convert.ToBase64String(
                    SHA1.Create().ComputeHash(
                        Encoding.UTF8.GetBytes(
                            new Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
                        )
                    )
                ) + Environment.NewLine
                + Environment.NewLine);

            stream.Write(response, 0, response.Length);

        }
        else
        {
            string msg = DecodeMessage(bytes);
            Console.WriteLine(msg);

            stream.Flush();
        }
        //Console.WriteLine(ByteToString(bytes));
    }

}



private string DecodeMessage(byte[] bytes)
{
    string incomingData = string.Empty;
    byte secondByte = bytes[1];
    int dataLength = secondByte & 127;
    int indexFirstMask = 2;
    if (dataLength == 126)
        indexFirstMask = 4;
    else if (dataLength == 127)
        indexFirstMask = 10;

    IEnumerable<byte> keys = bytes.Skip(indexFirstMask).Take(4);
    int indexFirstDataByte = indexFirstMask + 4;

    byte[] decoded = new byte[bytes.Length - indexFirstDataByte];
    for (int i = indexFirstDataByte, j = 0; i < bytes.Length; i++, j++)
    {
        decoded[j] = (byte)(bytes[i] ^ keys.ElementAt(j % 4));
    }

    return incomingData = Encoding.UTF8.GetString(decoded, 0, decoded.Length);
  }
}

I managed to receive the client messages using this :

 string msg = DecodeMessage(bytes);

but how can i send a message from the server back to the client ?

i am trying to build a websocket server but i can't manage to send a msg back to my client

Any help ?

Sora
  • 2,465
  • 18
  • 73
  • 146
  • Why do you want to build a WebSockets server if you don't know how sockets work? Don't you want to use a ready-built library for this? The code you show is fundamentally broken, does a lot of incorrect assumptions and requires a lot of fixing before it is a proper HTTP WebSockets server. Anyway, you're sending a handshake response at `stream.Write()`, why don't you use equal code to send a message response? – CodeCaster Dec 19 '15 at 16:40
  • i know how websocket work this is just a test server . it is not finish yet i know it have lots of bugs and i am trying to fix them , i can receive msgs from client but i can't send msg back i try this code : `byte[] srvMsg = Encoding.UTF8.GetBytes("Hi from server"); stream.Read(srvMsg, 0, srvMsg.Length); stream.Write(srvMsg, 0, srvMsg.Length);` after this line `string msg = DecodeMessage(bytes); Console.WriteLine(msg);` but nothing was received in the client side javascript code – Sora Dec 19 '15 at 17:34
  • I use this: http://stackoverflow.com/questions/14974404/socket-programming-multiple-client-one-server works very well – lin May 18 '17 at 20:40

2 Answers2

2
    public void SendString(string str)
    {
         //ns is a NetworkStream class parameter
        //logger.Output(">> sendind data to client ...", LogLevel.LL_INFO);
        try
        {

            var buf = Encoding.UTF8.GetBytes(str);
            int frameSize = 64;

            var parts = buf.Select((b, i) => new { b, i })
                            .GroupBy(x => x.i / (frameSize - 1))
                            .Select(x => x.Select(y => y.b).ToArray())
                            .ToList();

            for (int i = 0; i < parts.Count; i++)
            {
                byte cmd = 0;
                if (i == 0) cmd |= 1;
                if (i == parts.Count - 1) cmd |= 0x80;

                ns.WriteByte(cmd);
                ns.WriteByte((byte)parts[i].Length);
                ns.Write(parts[i], 0, parts[i].Length);
            }

            ns.Flush();
        }
        catch (Exception ex)
        {
            _srv.LogError(">> " + ex.Message);
        }

    }
-1

Sora, I think this link should help get you started: TCP Server/Client Intro

It contains source code for a very simple TCP Server/Client. Notice that after the server Accepts the socket, it reads from the stream, outputs that message, then proceeds to write an Acknowledgement to that stream.

On the client-side: After sending it's message, the client reads bytes from the same stream to get the server's acknowledgement.

Scott
  • 27
  • 1
  • 7
  • 1
    [Are answers that just contain links elsewhere really “good answers”?](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers) – CodeCaster Dec 19 '15 at 16:40
  • if the link to another good answer responds to the question, it is still a good answer. – Jean-François Feb 17 '20 at 11:25