在套接字读取之前替代 Thread.Sleep()

发布于 2024-10-14 06:39:20 字数 2205 浏览 2 评论 0原文

我正在使用此 FtpClient 库从 WinForms 应用程序连接到大型机。我使用 thread.Sleep 让线程在开始读取之前等待响应,否则它会冻结。有没有其他方法可以做到这一点?

public void Login() 
{
    if (this.loggedin) this.Close();

    Debug.WriteLine("Opening connection to " + this.server, "FtpClient");

    IPAddress addr = null;
    IPEndPoint ep = null;

    try
    {
        this.clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        addr = Dns.Resolve(this.server).AddressList[0];
        ep = new IPEndPoint(addr, this.port);
        this.clientSocket.Connect(ep);
    }
    catch (Exception ex)
    {
        // doubtfull
        if (this.clientSocket != null && this.clientSocket.Connected) this.clientSocket.Close();

        throw new FtpException("Couldn't connect to remote server", ex);
    }

    **Thread.Sleep(4000);**
    this.readResponse();
    ...
}

private void readResponse()
{
    this.message = "";
    this.result = this.readLine();

    if (this.result.Length > 3)
        this.resultCode = int.Parse(this.result.Substring(0, 3));
    else
        this.result = null;
}

private string readLine()
{
    while (true)
    {
        this.bytes = clientSocket.Receive(this.buffer, this.buffer.Length, 0);
        this.message += ASCII.GetString(this.buffer, 0, this.bytes);

        if (this.bytes < this.buffer.Length) break;
    }

    string[] msg = this.message.Split('\n');
    if (this.message.Length > 2)
    {
        this.message = msg[msg.Length - 2];
        try { response = msg[msg.Length - 3]; }
        catch { }
    }
    else
    {
        this.message = msg[0];
    }

    if (this.message.Length > 4 && !this.message.Substring(3, 1).Equals(" ")) return this.readLine();

    if (this.verboseDebugging)
    {
        for (int i = 0; i < msg.Length - 1; i++)
        {
            Debug.Write(msg[i], "FtpClient");
        }
    }
    return message;
}

public void sendCommand(String command)
{
    if (this.verboseDebugging) Debug.WriteLine(command, "FtpClient");

    Byte[] cmdBytes = Encoding.ASCII.GetBytes((command + "\r\n").ToCharArray());
    clientSocket.Send(cmdBytes, cmdBytes.Length, 0);
    this.readResponse();
}

I'm using this FtpClient library to connect to mainframe from WinForms application. I'm using thread.Sleep for the thread to wait for the response before it starts reading, otherwise it freezes. Is there an alternative to do this?

public void Login() 
{
    if (this.loggedin) this.Close();

    Debug.WriteLine("Opening connection to " + this.server, "FtpClient");

    IPAddress addr = null;
    IPEndPoint ep = null;

    try
    {
        this.clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        addr = Dns.Resolve(this.server).AddressList[0];
        ep = new IPEndPoint(addr, this.port);
        this.clientSocket.Connect(ep);
    }
    catch (Exception ex)
    {
        // doubtfull
        if (this.clientSocket != null && this.clientSocket.Connected) this.clientSocket.Close();

        throw new FtpException("Couldn't connect to remote server", ex);
    }

    **Thread.Sleep(4000);**
    this.readResponse();
    ...
}

private void readResponse()
{
    this.message = "";
    this.result = this.readLine();

    if (this.result.Length > 3)
        this.resultCode = int.Parse(this.result.Substring(0, 3));
    else
        this.result = null;
}

private string readLine()
{
    while (true)
    {
        this.bytes = clientSocket.Receive(this.buffer, this.buffer.Length, 0);
        this.message += ASCII.GetString(this.buffer, 0, this.bytes);

        if (this.bytes < this.buffer.Length) break;
    }

    string[] msg = this.message.Split('\n');
    if (this.message.Length > 2)
    {
        this.message = msg[msg.Length - 2];
        try { response = msg[msg.Length - 3]; }
        catch { }
    }
    else
    {
        this.message = msg[0];
    }

    if (this.message.Length > 4 && !this.message.Substring(3, 1).Equals(" ")) return this.readLine();

    if (this.verboseDebugging)
    {
        for (int i = 0; i < msg.Length - 1; i++)
        {
            Debug.Write(msg[i], "FtpClient");
        }
    }
    return message;
}

public void sendCommand(String command)
{
    if (this.verboseDebugging) Debug.WriteLine(command, "FtpClient");

    Byte[] cmdBytes = Encoding.ASCII.GetBytes((command + "\r\n").ToCharArray());
    clientSocket.Send(cmdBytes, cmdBytes.Length, 0);
    this.readResponse();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅忆 2024-10-21 06:39:20

使用异步编程模型:

socket.BeginConnect(ep, new AsyncCallback(Connected), socket);

void Connected (IAsyncResult result)
{
    var socket = (Socket)result.AsyncState;

    // do the stuff

    socket.EndConnect(result);
}

Use async programming model:

socket.BeginConnect(ep, new AsyncCallback(Connected), socket);

void Connected (IAsyncResult result)
{
    var socket = (Socket)result.AsyncState;

    // do the stuff

    socket.EndConnect(result);
}
东风软 2024-10-21 06:39:20

是的,如果您可以使用 .NET 4.0,那么您就拥有了任务 API。

您可以通过阅读本文了解更多信息:http: //www.codethinked.com/post/2010/01/25/NET-40-and-SystemThreadingTasks.aspx

它为您提供了一种创建流程的方法,在该流程中任务会等待直到前一个任务结束。看看吧!

Yes , if you can work with .NET 4.0, you've the task API.

You may learn more by reading this article: http://www.codethinked.com/post/2010/01/25/NET-40-and-SystemThreadingTasks.aspx

It provides you a way of creating a flow in which a task waits until previous one has ended. Take a look!

望喜 2024-10-21 06:39:20

编写 Thread.Sleep() 确实是一个不好的做法。

如果您实际上正在做 FTP 客户端,请使用 FtpWebRequest BeginGetResponse(asynccallback, object)

并传递 readResonse 作为回调。当响应准备好时,它将被准确调用。

Writing Thread.Sleep() is indeed a bad practice.

If you are actually doing a FTP client, use FtpWebRequest BeginGetResponse(asynccallback, object)

And pass the readResonse as a callback. It will be called exactly when the response is ready.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文