using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.NetworkInformation;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using MySql.Data.MySqlClient;
namespace ConsoleApplication3
{
    class Program
    {
        class ThreadedServer
        {
            private static int numberOfConnections;
            private Socket _serverSocket;
            private int _port;
            private string db_connect = "Database=supercourse;Data Source=localhost;User Id=root;Password=qwerasdf";
            private MySqlConnection myConnection;
            private MySqlConnection myConnection2;
            private int id;
            public ThreadedServer(int port)
            {
                _port = port;
                numberOfConnections = 0;
            }
            public void Start()
            {
                myConnection = new MySqlConnection(db_connect);
                myConnection2 = new MySqlConnection(db_connect);
                SetupServerSocket();
                for (int i = 0; i < 10; i++)
                    _serverSocket.BeginAccept(new
                    AsyncCallback(AcceptCallback), _serverSocket);
            }
            private class ConnectionInfo
            {
                public Socket Socket;
                public byte[] Buffer;
                public int user_id;
                public int char_id;
                public int id;
                public string nick;
                public float x;
                public float y;
                public float z;
            }
            private List<ConnectionInfo> _connections = new List<ConnectionInfo>();
            private void SetupServerSocket()
            {
                // Получаем информацию о локальном компьютере
                IPHostEntry localMachineInfo =
                Dns.GetHostEntry(Dns.GetHostName());
                IPEndPoint myEndpoint = new IPEndPoint(IPAddress.Any, _port);
                // Создаем сокет, привязываем его к адресу
                // и начинаем прослушивание
                _serverSocket = new Socket(
                myEndpoint.Address.AddressFamily,
                SocketType.Stream, ProtocolType.Tcp);
                _serverSocket.Bind(myEndpoint);
                _serverSocket.Listen((int)
                SocketOptionName.MaxConnections);
            }
            private void AcceptCallback(IAsyncResult result)
            {
                ConnectionInfo connection = new ConnectionInfo();
                try
                {
                    // Завершение операции Accept
                    Console.WriteLine("Подключился чел");
                    Socket s = (Socket)result.AsyncState;
                    connection.Socket = s.EndAccept(result);
                    connection.Buffer = new byte[256];
                    connection.id = _connections.Count() + 1;
                    lock (_connections) _connections.Add(connection);
                    // Начало операции Receive и новой операции Accept
                    connection.Socket.BeginReceive(connection.Buffer,
                    0, connection.Buffer.Length, SocketFlags.None,
                    new AsyncCallback(ReceiveCallback),
                    connection);
                    _serverSocket.BeginAccept(new AsyncCallback(
                    AcceptCallback), result.AsyncState);
                }
                catch (SocketException exc)
                {
                    CloseConnection(connection);
                    Console.WriteLine("95 Socket exception: " +
                    exc.SocketErrorCode);
                }
                catch (Exception exc)
                {
                    CloseConnection(connection);
                    Console.WriteLine("Exception: " + exc);
                }
            }
            private void ReceiveCallback(IAsyncResult result)
            {
                byte[] b;
                ConnectionInfo connection =
                (ConnectionInfo)result.AsyncState;
                try
                {
                    int bytesRead =
                    connection.Socket.EndReceive(result);
                    if (0 != bytesRead)
                    {
                        Console.WriteLine("Receive: Bytes: " + bytesRead);
                        lock (_connections)
                        {
                            string req = Encoding.UTF8.GetString(connection.Buffer, 0, 3);
                            switch (req)
                            {
                                case "lgn":
                                    Console.WriteLine("send req to db");
                                    b = LogIn(connection.Buffer);
                                    connection.Socket.Send(b);
                                    break;
                                case "gcr":
                                    b = GetChars(connection.Buffer);
                                    connection.Socket.Send(b);
                                    break;
                                case "crt":
                                    b = CreateChar(connection.Buffer);
                                    connection.Socket.Send(b);
                                    break;
                                case "dlt":
                                    b = DeleteChar(connection.Buffer);
                                    connection.Socket.Send(b);
                                    break;
                            }
                            /* else
                            foreach (ConnectionInfo conn in _connections)
                            {
                            if (conn != connection)
                            {
                            conn.Socket.Send(connection.Buffer, bytesRead, SocketFlags.None);
                            Console.WriteLine("bytes sent: "+bytesRead);
                            }
                            }*/
                        }
                        connection.Socket.BeginReceive(
                        connection.Buffer, 0,
                        connection.Buffer.Length, SocketFlags.None,
                        new AsyncCallback(ReceiveCallback),
                        connection);
                    }
                    else CloseConnection(connection);
                }
                catch (SocketException exc)
                {
                    CloseConnection(connection);
                    Console.WriteLine("216 Socket exception: " +
                    exc.SocketErrorCode);
                }
                catch (Exception exc)
                {
                    CloseConnection(connection);
                    Console.WriteLine("Exception: " + exc);
                }
            }
            private void CloseConnection(ConnectionInfo ci)
            {
                ci.Socket.Close();
                lock (_connections) _connections.Remove(ci);
                numberOfConnections--;
            }
            byte[] LogIn(byte[] b)
            {
                byte[] bf = new byte[32];
                string log = Encoding.UTF8.GetString(b, 10, BitConverter.ToInt32(b, 50));
                string psw = Encoding.UTF8.GetString(b, 30, BitConverter.ToInt32(b, 55));
                string request = "call SP_LogIn(" + "'" + log + "'" + "," + "'" + psw + "'" + ")";
                MySqlCommand myCommand = new MySqlCommand(request, myConnection);
                Int32 value = 0;
                try
                {
                    Console.WriteLine("trying open connection to db");
                    myConnection.Open();
                    value = Int32.Parse(myCommand.ExecuteScalar().ToString());
                    myConnection.Close();
                    Console.WriteLine("value = " + value);
                    Console.WriteLine("done sending req to bd. Value = " + value);
                }
                catch (Exception e)
                {
                    myConnection.Close();
                    Console.WriteLine(e.Message);
                }
                Encoding.UTF8.GetBytes("lgn").CopyTo(bf, 0);
                BitConverter.GetBytes(value).CopyTo(bf, 10);
                return bf;
            }
            byte[] GetChars(byte[] b)
            {
                byte[] bf = new byte[1024];
                int i = 0;
                string request = "call SP_GetChars(" + BitConverter.ToInt32(b, 3) + ")";
                MySqlCommand myCommand = new MySqlCommand(request, myConnection);
                try
                {
                    myConnection.Open();
                    MySqlDataReader MyDataReader;
                    MyDataReader = myCommand.ExecuteReader();
                    while (MyDataReader.Read())
                    {
                        int id = MyDataReader.GetInt32(0);
                        string name = MyDataReader.GetString(1);
                        Encoding.UTF8.GetBytes(name).CopyTo(bf, 10 + (i * 30));
                        BitConverter.GetBytes(id).CopyTo(bf, 30 + (i * 30));
                        i++;
                        // Console.WriteLine("id = "+id+" : name = "+name);
                    }
                    MyDataReader.Close();
                    myConnection.Close();
                    Console.WriteLine("i = " + i);
                    BitConverter.GetBytes(i).CopyTo(bf, 3);
                    Encoding.UTF8.GetBytes("gcr").CopyTo(bf, 0);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    myConnection.Close();
                }
                Console.WriteLine("sent chars = " + bf.Length + "bytes and i = " + i);
                return bf;
            }
            byte[] CreateChar(byte[] b)
            {
                byte[] bf = new byte[8];
                int id = BitConverter.ToInt32(b, 3);
                string name = Encoding.UTF8.GetString(b, 10, 20);
                string req = "call SP_CreateChar('" + id + "','" + name + "')";
                MySqlCommand command = new MySqlCommand();
                command.CommandText = req;
                command.Connection = myConnection;
                try
                {
                    myConnection.Open();
                    command.ExecuteScalar();
                    myConnection.Close();
                    BitConverter.GetBytes(1).CopyTo(bf, 3);
                }
                catch (Exception e)
                {
                    myConnection.Close();
                    Console.WriteLine(e.Message);
                    BitConverter.GetBytes(0).CopyTo(bf, 3);
                }
                Encoding.UTF8.GetBytes("crt").CopyTo(bf, 0);
                return bf;
            }
            byte[] DeleteChar(byte[] b)
            {
                byte[] bf = new byte[8];
                int id = BitConverter.ToInt32(b, 3);
                MySqlCommand command = new MySqlCommand();
                command.Connection = myConnection;
                command.CommandText = "call SP_DeleteChar('" + id + "')";
                try
                {
                    myConnection.Open();
                    command.ExecuteScalar();
                    myConnection.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    myConnection.Close();
                }
                BitConverter.GetBytes(id).CopyTo(bf, 3);
                Encoding.UTF8.GetBytes("dlt").CopyTo(bf, 0);
                Console.WriteLine("deleted");
                return bf;
            }
        }
        static void Main(string[] args)
        {
            ThreadedServer ts = new ThreadedServer(9095);
            ts.Start();
            Console.ReadLine();
        }
    }
}
Що за м'ютекси? оО Вперше чую про них