【问题标题】:TCPClient read-write - how to keep in syncTCPClient 读写 - 如何保持同步
【发布时间】:2013-06-23 21:31:16
【问题描述】:

我有一个基本的 IRC 客户端,它向服务器发送命令。在规范中它说 PASS 命令可以有 2 个数字回复 ERR_NEEDMOREPARAMS ERR_ALREADYREGISTRED

当我发送命令时,如果密码正确,则不会有回复,但如果密码不正确,我会得到两者之一。但是因为我的发送和接收是独立的,并且异步(使用等待异步)我没有可靠的方法来捕捉错误并停止发送NICKUSER 或任何其他命令的发送例程。

所以我的问题是,什么是绑定读写的好方法,这样我可以在出现问题时立即停止,并且通常随时严格控制通信。

【问题讨论】:

  • 当 PASS 正确时,您不会收到回复,否则您会收到错误消息,好吧,我会在继续之前使用 Socket.poll() 命令等待几秒钟。如果在那段时间内套接字是可读的,有一些数据,这意味着你有一个答案,这意味着它是一个错误的 PASS 或其他什么。

标签: c# sockets network-programming tcpclient irc


【解决方案1】:

你去吧,一个简单的同步客户端套接字示例:

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

public class SynchronousSocketClient {

public static void StartClient() {
    // Data buffer for incoming data.
    byte[] bytes = new byte[1024];

    // Connect to a remote device.
    try {
        // Establish the remote endpoint for the socket.
        // This example uses port 11000 on the local computer.
        IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName())
        IPAddress ipAddress = ipHostInfo.AddressList[0];
        IPEndPoint remoteEP = new IPEndPoint(ipAddress,11000);

        // Create a TCP/IP  socket.
        Socket sender = new Socket(AddressFamily.InterNetwork, 
            SocketType.Stream, ProtocolType.Tcp );

        // Connect the socket to the remote endpoint. Catch any errors.
        try {
            sender.Connect(remoteEP);

            Console.WriteLine("Socket connected to {0}",
                sender.RemoteEndPoint.ToString());

            // Encode the data string into a byte array.
            byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>");

            // Send the data through the socket.
            int bytesSent = sender.Send(msg);

            // Receive the response from the remote device.
            int bytesRec = sender.Receive(bytes);
            Console.WriteLine("Echoed test = {0}",
                Encoding.ASCII.GetString(bytes,0,bytesRec));

            // Release the socket.
            sender.Shutdown(SocketShutdown.Both);
            sender.Close();

        } catch (ArgumentNullException ane) {
            Console.WriteLine("ArgumentNullException : {0}",ane.ToString());
        } catch (SocketException se) {
            Console.WriteLine("SocketException : {0}",se.ToString());
        } catch (Exception e) {
            Console.WriteLine("Unexpected exception : {0}", e.ToString());
        }

    } catch (Exception e) {
        Console.WriteLine( e.ToString());
    }
}

public static int Main(String[] args) {
    StartClient();
    return 0;
   }
}

【讨论】:

  • 如果服务器没有响应,这将如何工作,它会永远阻塞吗?
  • 这是启动同步转换的方式,你可以随时创建循环等待服务器。
【解决方案2】:

PASS 被接受或拒绝之前,没有必要避免发送NICKUSER - 正如您所指出的,您实际上无法知道它是否已被接受。

您应该立即发送NICKUSERPASS 命令,不要延迟,然后等待查看其中一个或任何一个是否被拒绝(在这种情况下,您将收到错误数字)或所有这些都被接受(在这种情况下,您将获得RPL_WELCOME 数字)。注册命令的发送没有固定的顺序,例如,如果您已经发送了NICKUSER,是否必须重新发送PASS 也没关系。

【讨论】:

    猜你喜欢
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 2015-01-12
    • 1970-01-01
    相关资源
    最近更新 更多