Как бы я постоянно слушать порт с графическим интерфейсом? - PullRequest
4 голосов
/ 02 марта 2012

Эй, ребята, я пытаюсь изучить взаимодействие TCP-сервера с клиентом.Я хочу знать, как я буду слушать порт все время с графическим интерфейсом.В настоящее время я использую этот код:

    private void Form1_Load(object sender, EventArgs e)
    {
        CreateServer();
    }

    void CreateServer()
    {
        TcpListener tcp = new TcpListener(25565);
        tcp.Start();

        Thread t = new Thread(() =>
        {

            while (true)
            {
                var tcpClient = tcp.AcceptTcpClient();

                ThreadPool.QueueUserWorkItem((_) =>
                {
                    Socket s = tcp.AcceptSocket();

                    console.Invoke((MethodInvoker)delegate { console.Text += "Connection esatblished: " + s.RemoteEndPoint + Environment.NewLine; });

                    byte[] b = new byte[100];
                    int k = s.Receive(b);


                    for (int i = 0; i < k; i++)
                    {
                        console.Text += Convert.ToChar(b[i]);
                        incoming += Convert.ToChar(b[i]);
                    }

                    MessageBox.Show(incoming);

                    console.Invoke((MethodInvoker)delegate { console.Text += incoming + Environment.NewLine; });

                    list.Invoke((MethodInvoker)delegate { list.Items.Add(incoming); });

                    ASCIIEncoding asen = new ASCIIEncoding();
                    s.Send(asen.GetBytes("\n"));

                    tcpClient.Close();
                }, null);
            }
        });
        t.IsBackground = true;
        t.Start();
    }

Любая помощь будет высоко ценится.

Ответы [ 4 ]

4 голосов
/ 02 марта 2012

Краткий ответ - запустите прослушиватель TCP в отдельном потоке / задании (TPL).Для полноценного рабочего решения вы также должны реализовать отправку любых изменений в пользовательском интерфейсе из отдельного потока в основной поток, используя специальную технику, которая зависит от используемой вами платформы, я имею в виду WPF / WinForms / что угодно.

Код нижеу меня работает нормально.Прочитайте раздел TODO.

TODO:

  • Добавить в форму Textbox, ListBox, Button, сделать общедоступным:

    public System.Windows.Forms.TextBox console;
    public System.Windows.Forms.ListBox incommingMessages;
    private System.Windows.Forms.Button sendSampleDataButton;
    

Точка входа:

private static Form1 form;

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    form = new Form1();
    form.Load += OnFormLoad;
    Application.Run(form);
}

private static void OnFormLoad(object sender, EventArgs e)
{
    CreateServer();
}

Сервер:

private static void CreateServer()
{
    var tcp = new TcpListener(IPAddress.Any, 25565);
    tcp.Start();

    var listeningThread = new Thread(() =>
    {
        while (true)
        {
            var tcpClient = tcp.AcceptTcpClient();
            ThreadPool.QueueUserWorkItem(param =>                                                            
            {                        
                NetworkStream stream = tcpClient.GetStream();
                string incomming;                        
                byte[] bytes = new byte[1024];
                int i = stream.Read(bytes, 0, bytes.Length);                                                
                incomming = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
                form.console.Invoke(
                (MethodInvoker)delegate
                    {
                        form.console.Text += String.Format(
                            "{0} Connection esatblished: {1}{2}", 
                            DateTime.Now,
                            tcpClient.Client.RemoteEndPoint,
                            Environment.NewLine);
                    });

                MessageBox.Show(String.Format("Received: {0}", incomming));
                form.incommingMessages.Invoke((MethodInvoker)(() => form.incommingMessages.Items.Add(incomming)));
                tcpClient.Close();
            }, null);
        }
    });

    listeningThread.IsBackground = true;
    listeningThread.Start();
}

Клиент

private void button1_Click(object sender, EventArgs e)
{
    Connect("localhost", "hello localhost " + Guid.NewGuid());
}

static void Connect(String server, String message)
{
    try
    {               
        Int32 port = 25565;
        TcpClient client = new TcpClient(server, port);             
        Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);
        NetworkStream stream = client.GetStream();

        // Send the message to the connected TcpServer. 
        stream.Write(data, 0, data.Length);                                
        stream.Close();
        client.Close();
    }
    catch (ArgumentNullException e)
    {
        Debug.WriteLine("ArgumentNullException: {0}", e);
    }
    catch (SocketException e)
    {
        Debug.WriteLine("SocketException: {0}", e);
    }          
}

Снимок экрана:

enter image description here

2 голосов
/ 02 марта 2012

Создать тему, начать слушать в ней и не останавливать сервер

void CreateServer()
{
    TcpListener tcp = new TcpListener(25565);
    tcp.Start();

    Thread t = new Thread(()=>
    {
        while (true)
        {
            var tcpClient = tcp.AcceptTcpClient();
            ThreadPool.QueueUserWorkItem((_) =>
            {
                //Your server codes handling client's request.
                //Don't access UI control directly here
                //Use "Invoke" instead. 
                tcpClient.Close();
            },null);
        }
    });
    t.IsBackground = true;
    t.Start();
}
1 голос
/ 02 марта 2012

Вы можете использовать подход потоков (как упоминалось в других ответах) или использовать асинхронные сокеты , что в моем мнении намного лучше. И даже лучше, вы можете использовать асинхронную модель, предложенную SocketAsyncEventArgs . Асинхронные сокеты получат преимущества от использования портов завершения .

0 голосов
/ 02 марта 2012
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...