C#TCP服务器无法响应客户端

C#TCP服务器无法响应客户端,c#,tcp,networkstream,tcpserver,C#,Tcp,Networkstream,Tcpserver,所以我现在的工作是创建一个服务器,它可以同时响应和连接多个客户机,这就是为什么我要创建一个线程服务器和一些测试客户机来进行检查 客户端可以通过按下按钮连接到服务器,它会向服务器发送消息,服务器会将消息发送到其接口,然后响应客户端。最后,客户机将接收响应并将其放到其接口上 我现在遇到的问题是服务器可以接收来自服务器的消息并显示,但是服务器对客户端的响应并不成功,即使它们是相似的。从调试器上看,客户端似乎在读取过程中卡住了 下面是我的服务器代码。我认为问题出现在连接处理程序和客户端。我现在卡住了,请

所以我现在的工作是创建一个服务器,它可以同时响应和连接多个客户机,这就是为什么我要创建一个线程服务器和一些测试客户机来进行检查

客户端可以通过按下按钮连接到服务器,它会向服务器发送消息,服务器会将消息发送到其接口,然后响应客户端。最后,客户机将接收响应并将其放到其接口上

我现在遇到的问题是服务器可以接收来自服务器的消息并显示,但是服务器对客户端的响应并不成功,即使它们是相似的。从调试器上看,客户端似乎在读取过程中卡住了

下面是我的服务器代码。我认为问题出现在连接处理程序和客户端。我现在卡住了,请告诉我我做错了什么@@

public class Server
{
    TcpListener serverSocket = new TcpListener(IPAddress.Any, 3000);
    TcpClient clientSocket = default(TcpClient);
    int counter = 0;
    private exampleCallback callback;

    public Server(exampleCallback Callback)
    {
        callback = Callback;
    }

    public void initServer()
    {
        serverSocket.Start();

        //Call back to main thread to update display
        if (callback != null)
            callback(">> Server Initialized!");

        Console.WriteLine(">> Server Initialized!");
    }

    public void waitConnection()
    {
        int counter = 0;
        while (true)
        {
            counter += 1;
            clientSocket = serverSocket.AcceptTcpClient();

            if (callback != null)
                callback(">> Client number: " + counter + " started!");

            Console.WriteLine(">> Client number: " + counter + " started!");

            handleClient handerler = new handleClient(new exampleCallback(receiveCallback), clientSocket, counter);
            Thread clientThread = new Thread(new ThreadStart(handerler.startConv));
            clientThread.Start();
        }
    }

    public void closeServer()
    {
        clientSocket.Close();
        serverSocket.Stop();
    }

    private void receiveCallback(string message)
    {
        callback(message);
    }


}
连接Handlerer的代码:

public class handleClient
{
    private exampleCallback callback2;
    TcpClient clientSocket;
    int clientNo;

    public handleClient(exampleCallback Callback, TcpClient client, int clNo)
    {
        callback2 = Callback;
        clientSocket = client;
        clientNo = clNo;
    }

    public void startConv()
    {
        int requestCount = 0; 
        byte[] byteFrom = new byte[10025];
        string XMLfromClient = null;
        string dataFromClient = null; 
        string serverResponse = null;
        string serverXMLResponse = null;
        NetworkStream serverStream = clientSocket.GetStream();

        requestCount = 0;
        while (true)
        {
            try
            {
                requestCount++;

                //Receive requerst from client
                serverStream.Read(byteFrom, 0, (int)clientSocket.ReceiveBufferSize);
                XMLfromClient = System.Text.Encoding.ASCII.GetString(byteFrom);
                callback2("\n >> From Client :" + clientNo + ". Message: \n" + XMLfromClient);


                //Console.WriteLine(">> From Client :" + clientNo + ". Message: \n" + XMLfromClient);

                //Send acknowledgement to client
                serverResponse = "Server to Client(" + clientNo + "). Request time: " + requestCount;  
                byte[] byteTo = Encoding.ASCII.GetBytes(serverResponse);
                serverStream.Write(byteTo, 0, byteTo.Length);

                serverStream.Flush();
                Console.WriteLine(">> " + serverResponse);
            }
            catch (Exception ex)
            {
                callback2(ex.ToString()); 
            }
        }
    }
}
最后是客户端大小的代码:

public partial class Form1 : Form
{
    System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
    NetworkStream serverStream;

    public Form1()
    {
        InitializeComponent();
    }

    public void msg(string mesg)
    {
        this.Display.Text += Environment.NewLine + " >> " + mesg;
    }

    private void SendButton_Click(object sender, EventArgs e)
    {
        serverStream = clientSocket.GetStream();
        byte[] outStream = System.Text.Encoding.ASCII.GetBytes("World Domination");
        serverStream.Write(outStream, 0, outStream.Length);
        serverStream.Flush();
        Thread receive = new Thread(new ThreadStart(ReceiveMess));

    }

    private void ReceiveMess()
    {
        serverStream = clientSocket.GetStream();
        byte[] inStream = new byte[10025];
        serverStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
        string returndata = System.Text.Encoding.ASCII.GetString(inStream);
        msg("Data from Server : " + returndata);
    }
    private void connectButton_Click(object sender, EventArgs e)
    {
        msg("Client Started");
        clientSocket.Connect("127.0.0.1", 3000);
        this.Display.Text = "Client Socket Program - Server Connected ...";
    }
}

您似乎忘记启动
receive
线程:

private void SendButton_Click(object sender, EventArgs e)
{
    // ... skipped .........
    Thread receive = new Thread(new ThreadStart(ReceiveMess));
    receive.Start(); // <--- try adding this line
}
private void SendButton\u单击(对象发送者,事件参数e)
{
//跳过。。。。。。。。。
线程接收=新线程(新线程开始(接收));
receive.Start();//
服务器将向其接口发送消息,然后响应客户端

那么服务器是一个GUI应用程序

根据GUI线程上似乎有阻塞操作(例如,
AcceptCpcClient
)的代码。这将失败。GUI线程将阻塞(UI将无响应),这意味着工作人员对IO的更新将阻塞等待UI的操作(所有UI操作必须在主线程上进行)

另外,为每个连接旋转一个新线程是一个坏主意。线程是昂贵的

您需要从一开始就重写(客户端和服务器)

  • 避免在GUI线程上阻塞操作(即使是文件IO,如果您希望获得最大性能)/
  • 所有套接字操作都应该在线程池中运行(让系统为您管理线程)
  • 避免从后台线程等待GUI(首选
    BeginInvoke
    而不是
    Invoke

更好的方法是使用
async
:系统将为您管理线程切换。

这里有一些问题(可能与您的问题无关)-
Read
返回读取的字节数。不能保证这与您要求的字节数匹配。您当前正在忽略这些返回值。此外,TCP是一个字节流-如果您想要“消息”,您必须为这些实现框架-无法保证一端的
写入
调用将与另一端的
读取
调用1-1匹配。是的,我已经四处走动了大约半天!非常感谢,您是我的救星:vSorry无法对您的评论进行投票,因为它需要15个声誉,我只做了一个简单的评论新帐户,但非常感谢您:v@TuAnhDang:不客气!如果您愿意,您可以接受答案:)不,实际上我从GUI中删除了服务器端,因此当服务器开始侦听时,系统将生成一个新线程来侦听,这样它就不会阻塞。回调方法用于在工作线程和主线程之间传输信息eads。