Как правильно приостановить / остановить поток? - PullRequest
1 голос
/ 19 марта 2019

Я работал над клиентом чата в C #.Я пытаюсь найти способ приостановить / остановить поток при отключении от сервера.Прямо сейчас, когда я нажимаю на разъединение, он должен отправить сообщение {quit} на сервер, но после этого клиент просто блокируется, потому что поток получения все еще работает, пытаясь получить данные от сервера, когда он отключен.Кто-нибудь знает хороший способ справиться с этим?

Вот код:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;


namespace sockjtest
{
    public partial class Form1 : Form
    {

        System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
        NetworkStream serverStream = default(NetworkStream);
        string readData = null;

        public Form1()
        {
            InitializeComponent();
        }

    private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        // send from sendbox
        private void button1_Click(object sender, EventArgs e)
        {


            byte[] outStream = System.Text.Encoding.UTF8.GetBytes(sendbox.Text);
            serverStream.Write(outStream, 0, outStream.Length);
            serverStream.Flush();

            sendbox.Clear();           
        }

        private void recievebox_TextChanged(object sender, EventArgs e)
        {


        }

        // send username to server once connected
        private void sendusr()
        {

            byte[] userStream = System.Text.Encoding.UTF8.GetBytes(usernamebox.Text);
            serverStream.Write(userStream, 0, userStream.Length);
            serverStream.Flush();

        }

        // connect button

        private void button2_Click(object sender, EventArgs e)
        {
            Thread ctThread = new Thread(recievestream);

            if (conntectbutton.Text.Contains("Connect") == true)
            {



                string srvip = serverip.Text;
                int srvport = Convert.ToInt32(serverport.Text);
                try
                {
                    clientSocket.Connect(srvip, srvport);
                    if (clientSocket.Connected)
                    {

                        // change button state
                        conntectbutton.Text = "Disconnect";
                        recievebox.Clear();
                        recievebox.AppendText("*** Connected to " + srvip + ":" + srvport + " ***\r\n");

                        // start recieve thread
                        serverStream = clientSocket.GetStream();
                        ctThread.Start();
                        // call send user function
                        sendusr();

                    }

                }

                catch (System.Net.Sockets.SocketException)
                {
                    recievebox.Clear();
                    recievebox.AppendText("*** Could not connected to " + srvip + ":" + srvport + " ***");
                }
            } else
            {
                string quitmsg = "{quit}";
                byte[] quitstream = System.Text.Encoding.UTF8.GetBytes(quitmsg);
                serverStream.Write(quitstream, 0, quitstream.Length);
                serverStream.Flush();

                Thread.Sleep(3000);
                ctThread.Abort();

                conntectbutton.Text ="Connect";
            }


        }

        private void serverip_TextChanged(object sender, EventArgs e)
        {

        }

        private void serverport_TextChanged(object sender, EventArgs e)
        {

        }

        // recieve
        private void recievestream()
        {
            while (true)
            {


                NetworkStream serverStream = clientSocket.GetStream();
                int buffSize = 0;
                byte[] inStream = new byte[1024];
                int bytesRead = serverStream.Read(inStream, 0, inStream.Length);
                buffSize = clientSocket.ReceiveBufferSize;
                string returndata = System.Text.Encoding.UTF8.GetString(inStream, 0, bytesRead);
                readData = "" + returndata;
                msg();

            }
        }

        // print message to recievebox
        private void msg()
        {
            if (this.InvokeRequired)
                this.Invoke(new MethodInvoker(msg));
            else
                recievebox.Text = recievebox.Text + Environment.NewLine + readData;
        }

        private void usernamebox_TextChanged(object sender, EventArgs e)
        {

        }

    }
}

Ответы [ 2 ]

0 голосов
/ 19 марта 2019

Мне удалось это исправить, заставив сервер отправить обратно сообщение {quit} клиенту. При получении он закроет сокет, а затем повторно инициализирует его, чтобы можно было снова подключиться к серверу.

0 голосов
/ 19 марта 2019

изменить while(true) на while(clientSocket.Connected) затем, когда удаленный сервер отключил соединение, ваш цикл будет автоматически разорван;

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