简体   繁体   English

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

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

I'm developing a networking application. 我正在开发网络应用程序。 The server program gives questions, then clients enters their answers. 服务器程序提出问题,然后客户输入答案。 Actually, both server program and client program were console program. 实际上,服务器程序和客户端程序都是控制台程序。 But, when I changed client program to Form program, It doesn't display. 但是,当我将客户端程序更改为Form程序时,它不会显示。 (ONLY WHEN I TURN ON SERVER PROGRAM!) It works when i don't start server program. (仅当我打开服务器程序时!)它在我不启动服务器程序时有效。

Here's my server program code, 这是我的服务器程序代码,

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
        }
    }
}

and here's my client program code, 这是我的客户程序代码,

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++;
        }

    }
}

How can I solve this problem?? 我怎么解决这个问题?? Thanks for reading my question! 感谢您阅读我的问题!

Since you are already using NetworkStream , fixing the client code is easy. 由于您已经在使用NetworkStream ,因此修复客户端代码很容易。 Just switch over to the async / await idiom: 只需切换到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;
            }
        }
    }
}

Now, that said, you had and still have some other bugs. 就是说,您曾经并且仍然有一些其他错误。 First, your original code had a loop that read from the stream until the return value was 0. All that's going to do is consume the data in the stream without processing any of it. 首先,您的原始代码有一个循环,该循环从流中读取数据, 直到返回值为0。所有要做的就是在不处理任何数据的情况下使用流中的数据。 Very bad. 很坏。 I removed that bug completely in the example above. 我在上面的示例中完全删除了该错误。

Second, you are not checking the return value of the read. 其次,您不检查读取的返回值。 TCP guarantees only one thing: that if you receive any data, the bytes that you receive are in the same order in which they were sent. TCP仅保证一件事: 如果您接收到任何数据,则接收到的字节将按照其发送的顺序。 In particular, there are no guarantees about how many bytes you'll receive in any given call to Read() . 特别是,无法保证在任何给定的Read()调用中您将收到多少字节。 If the remote endpoint sends 100 bytes, you could receive all 100 bytes all at once, or you could receive 1 byte at a time in 100 calls to Read() . 如果远程端点发送了100个字节,则您可以一次全部接收所有100个字节,或者您可以在100次对Read()调用中一次接收1个字节。

(Well, actually that's highly unlikely to ever happen...but it's not prohibited by the TCP contract, and in any case if you assume it's true you'll write correct code). (好吧,其实这是非常不可能不会发生......但它不是由TCP合同禁止的,在任何情况下,如果你认为这是真的,你会写正确的代码)。

That's really a whole other question. 这确实是另一个问题。 The above will get your Forms program back to working, in that you'll actually be able to see the Form and interact with it. 上面的代码将使您的Forms程序恢复正常工作,因为您实际上将能够看到Form并与其进行交互。 And the network code might even seem to work for awhile. 而且网络代码似乎甚至可以工作一段时间。 But eventually you'll get a partial message, or multiple messages combined into one, or some other variation on that theme. 但是最终您会得到部分消息,或者将多条消息组合成一个消息,或者对该主题进行一些其他变化。

When that happens, IMHO one of the easiest ways to fix that in a scenario like yours is to switch to a line-based data scheme. 发生这种情况时,恕我直言,在像您这样的情况下解决此问题的最简单方法之一就是切换到基于行的数据方案。 Ie wrap the NetworkStream object in StreamReader and StreamWriter objects, and use the ReadLineAsync() method to receive data instead of the NetworkStream.Read() method. 即,将NetworkStream对象包装在StreamReaderStreamWriter对象中,并使用ReadLineAsync()方法代替NetworkStream.Read()方法来接收数据。 Regardless, feel free to post another question when you come to that bridge. 无论如何,当您来到那座桥时,随时可以提出另一个问题。 :) :)

暂无
暂无

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

相关问题 C#“ Thread.Sleep”困扰我的程序(窗体不显示) - C# “Thread.Sleep” Messing My Program (Form Doesn't Show Up) 如果我的客户端程序是Java而不是C#,为什么必须添加服务器SSL证书? - Why do I have to add the server SSL certificate if my client program is in Java and not when it is in C#? 在Visual C ++ / C#中,我可以编译一个程序,使其在崩溃时不显示消息框吗? - In Visual C++/C#, can I compile a program such that it doesn't show a message box if it crashes? Windows 10 Search中不显示C#WPF程序 - C# WPF program doesn't show in Windows 10 Search 如何编译一个在执行时不显示“Unknown Publisher”的C#程序 - How to compile a C# program that doesn't show “Unknown Publisher” when executed 我的索引在启动程序时没有显示任何内容,但是当我使用来自互联网的代码时 - My Index doesn't show anything when starting the program but when I use code from the internet it does C#中的多客户端/服务器聊天程序? - multi client/server chat program in c#? 当我运行我的程序时,我在 C# 中得到“从服务器返回了一个引用” - When I run my program I get “a referral was returned from the server” in C# 当我点击右上角的 X 按钮时程序没有关闭(Visual Studio、Forms、C#) - Program doesn't close when I hit the X button top right (Visual Studio, Forms, C#) 客户端运行我的程序后,c#在打开excel时始终打开该程序编写的excel工作表 - c# after client runs my program the excel sheet the program writes always opens when excel is opened
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM