繁体   English   中英

C#网络-启动服务器程序时未显示我的表单(客户端程序)

[英]C# network - My form(client program) doesn't show when I start server program

我正在开发网络应用程序。 服务器程序提出问题,然后客户输入答案。 实际上,服务器程序和客户端程序都是控制台程序。 但是,当我将客户端程序更改为Form程序时,它不会显示。 (仅当我打开服务器程序时!)它在我不启动服务器程序时有效。

这是我的服务器程序代码,

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace Server
{
    public class TaskInfo
    {
        public Socket client;
        public int thread_num;              
        public int q_num;                   

        public ManualResetEvent doneEvent;  

        public TaskInfo(Socket c, int n, int q, ManualResetEvent d)
        {
            client = c;
            thread_num = n;
            q_num = q;
            doneEvent = d;
        }
    }

    public class ServerTCP
    {
        static int num_client = 2;
        static bool[] check_co_client = new bool[num_client];
        static int num_co_client = 0;

        static void ClientHandler(Object task_info)
        {
            TaskInfo ti = (TaskInfo)task_info;

            // Casting of object
            Socket client = (Socket)ti.client;
            IPEndPoint endpoint = (IPEndPoint)client.RemoteEndPoint;

            //Console.WriteLine("{0} connected at port {1}", endpoint.Address, endpoint.Port);

            int index = ti.q_num;

            byte[] buffer = new byte[256];
            int byteRecv = 0;
            string message = "";

            string[] questions = new string[5];
            questions[0] = "0. What is 5+6?";
            questions[1] = "1. What is 1+3?";
            questions[2] = "2. What is 5+3?";
            questions[3] = "3. What is 1+1?";
            questions[4] = "4. What is 9-5?";

            string[] answers = new string[5];
            answers[0] = "11";
            answers[1] = "4";
            answers[2] = "8";
            answers[3] = "2";
            answers[4] = "4";

            try
            {
                // Send message to client
                buffer = Encoding.ASCII.GetBytes(questions[index]);
                client.Send(buffer, buffer.Length, SocketFlags.None);

                // Receive data from client
                byteRecv = client.Receive(buffer);
                message = Encoding.ASCII.GetString(buffer, 0, byteRecv);

                if (message == answers[ti.q_num])
                {
                    check_co_client[ti.thread_num] = true;
                }
                else
                {
                    check_co_client[ti.thread_num] = false;
                }

                ti.doneEvent.Set();

            }
            catch (SocketException se)
            {
                Console.WriteLine("{0}: {1} [{2}:{3}]", se.ErrorCode, se.Message, endpoint.Address, endpoint.Port);
            }
            finally
            {
                // Close socket
                //client.Close();
            }
        }

        public static void Main()
        {
            TcpListener listener = null;

            try
            {
                // Create new instance and start listening
                listener = new TcpListener(IPAddress.Any, 8080);
                listener.Start();

                Console.WriteLine("<Waiting for clients connection>");

                // Accept the client connection
                Socket[] client = new Socket[num_client];
                int count = 0;
                while (count < num_client)
                {
                    client[count] = listener.AcceptSocket();
                    count++;
                }

                ManualResetEvent[] doneEvents = new ManualResetEvent[num_client];

                // Start threads
                Thread[] t = new Thread[num_client];

                for (int q_num = 0; q_num < 5; q_num++)
                {
                    for (int i = 0; i < num_client; i++)
                    {
                        doneEvents[i] = new ManualResetEvent(false);
                        TaskInfo ti = new TaskInfo(client[i], i, q_num, doneEvents[i]);

                        t[i] = new Thread(ClientHandler);
                        t[i].Start(ti);

                    }

                    WaitHandle.WaitAll(doneEvents);

                    Thread.Sleep(2000);

                    // count clients who enter correct answer
                    for (int index = 0; index < num_client; index++)
                    {
                        if (check_co_client[index])
                        {
                            num_co_client++;
                        }
                    }
                    Console.WriteLine("number of correct answers: {0}", num_co_client);
                    num_co_client = 0;
                }
            }
            catch (SocketException se)
            {
                Console.WriteLine("Error Code: {0}", se.ErrorCode);
                Console.WriteLine("Message: {0}", se.Message);
            }
            finally
            {
                listener.Stop();
            }

            Console.ReadLine(); // Pause for IDE
        }
    }
}

这是我的客户程序代码,

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

namespace Client_Form
{
    public partial class Client_Form : Form
    {
        TcpClient client = null;
        NetworkStream stream = null;
        int count = 0;

        public Client_Form()
        {
            InitializeComponent();

            Start_Program();

        }

        private void Start_Program()
        {
            try
            {
                // Connect to server
                client = new TcpClient("127.0.0.1", 8080);
                //Console.WriteLine("<Connected to server>");
                textBox.Text = "<Connected to server>";

                stream = client.GetStream();

                byte[] buffer = new byte[256];
                int byteRecv = 0;
                string message = "";

                int q_count = 5;

                while (count < q_count)
                {
                    while ((byteRecv = stream.Read(buffer, 0, buffer.Length)) == 0)
                    {
                        textBox.Text = "Waiting for other client";

                        Thread.Sleep(3000);
                    }

                    // Get data from server
                    //byteRecv = stream.Read(buffer, 0, buffer.Length);
                    message = Encoding.ASCII.GetString(buffer, 0, byteRecv);

                    Co_Game_Question.Text = message;

                }

                // Close stream and connection
                stream.Close();
                client.Close();

                //Console.WriteLine("<Connection closed>");
                textBox.Text = "<Connection closed>";
            }
            catch (SocketException se)
            {
                //Console.WriteLine("Error: {0}", se.SocketErrorCode);
                //Console.WriteLine("Error Code: {0}", se.ErrorCode);
                //Console.WriteLine("Message: {0}", se.Message);
                textBox.Text = "Error Message: " + se.Message;
            }
        }

        private void Btn_Enter_Click(object sender, EventArgs e)
        {
            // Send message to server
            //Console.Write("Answer {0}> ", count);
            //textBox.Text = "Answer " + count + "> ";

            byte[] data = Encoding.ASCII.GetBytes(User_answer_box.Text);
            stream.Write(data, 0, data.Length);

            count++;
        }

    }
}

我怎么解决这个问题?? 感谢您阅读我的问题!

由于您已经在使用NetworkStream ,因此修复客户端代码很容易。 只需切换到async / await习惯用法即可:

namespace Client_Form
{
    public partial class Client_Form : Form
    {
        TcpClient client = null;
        NetworkStream stream = null;
        int count = 0;

        public Client_Form()
        {
            InitializeComponent();
        }

        protected override void OnLoad(EventArgs e)
        {
            // Handling the network operations after the form loads ensures
            // that the asynchronous operations will come back to the main
            // thread as desired.

            // Ignore returned Task
            var _ = Start_Program();
        }

        private async void Start_Program()
        {
            try
            {
                // Connect to server
                client = await Task.Run(() => new TcpClient("127.0.0.1", 8080));
                textBox.Text = "<Connected to server>";

                stream = client.GetStream();

                byte[] buffer = new byte[256];
                int q_count = 5;

                while (count < q_count)
                {
                    textBox.Text = "Waiting for other client";

                    // Get data from server
                    int byteRecv = await stream.ReadAsync(buffer, 0, buffer.Length);
                    string message = Encoding.ASCII.GetString(buffer, 0, byteRecv);

                    Co_Game_Question.Text = message;

                }

                // Close stream and connection
                stream.Close();
                client.Close();

                textBox.Text = "<Connection closed>";
            }
            catch (SocketException se)
            {
                textBox.Text = "Error Message: " + se.Message;
            }
        }
    }
}

就是说,您曾经并且仍然有一些其他错误。 首先,您的原始代码有一个循环,该循环从流中读取数据, 直到返回值为0。所有要做的就是在不处理任何数据的情况下使用流中的数据。 很坏。 我在上面的示例中完全删除了该错误。

其次,您不检查读取的返回值。 TCP仅保证一件事: 如果您接收到任何数据,则接收到的字节将按照其发送的顺序。 特别是,无法保证在任何给定的Read()调用中您将收到多少字节。 如果远程端点发送了100个字节,则您可以一次全部接收所有100个字节,或者您可以在100次对Read()调用中一次接收1个字节。

(好吧,其实这是非常不可能不会发生......但它不是由TCP合同禁止的,在任何情况下,如果你认为这是真的,你会写正确的代码)。

这确实是另一个问题。 上面的代码将使您的Forms程序恢复正常工作,因为您实际上将能够看到Form并与其进行交互。 而且网络代码似乎甚至可以工作一段时间。 但是最终您会得到部分消息,或者将多条消息组合成一个消息,或者对该主题进行一些其他变化。

发生这种情况时,恕我直言,在像您这样的情况下解决此问题的最简单方法之一就是切换到基于行的数据方案。 即,将NetworkStream对象包装在StreamReaderStreamWriter对象中,并使用ReadLineAsync()方法代替NetworkStream.Read()方法来接收数据。 无论如何,当您来到那座桥时,随时可以提出另一个问题。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM