C# 不允许发送或接收数据的请求,因为套接字未连接且未提供地址

C# 不允许发送或接收数据的请求,因为套接字未连接且未提供地址,c#,wpf,sockets,C#,Wpf,Sockets,我已经阅读了Stackoverflow上所有关于这个问题的帖子,但没有一篇解决了我的问题。 我已为正在构建的使用TCP套接字的客户端服务器应用程序创建了身份验证类: public class Authentication { private Socket _socket; private AddressFamily _addressFamily; private SocketType _socketType; private ProtocolType _protocolType; private

我已经阅读了Stackoverflow上所有关于这个问题的帖子,但没有一篇解决了我的问题。 我已为正在构建的使用TCP套接字的客户端服务器应用程序创建了身份验证类:

public class Authentication
{
private Socket _socket;
private AddressFamily _addressFamily;
private SocketType _socketType;
private ProtocolType _protocolType;
private IPAddress _ipAddress;
private IPEndPoint _ipEndPoint;

private bool _running = true;

public Authentication(SocketType socketType, AddressFamily family, ProtocolType protocolType)
{
    _addressFamily = family;
    _socketType = socketType;
    _protocolType = protocolType;
}

public int Connect(string ipAdd, int port)
{
    try
    {
        _addressFamily = AddressFamily.InterNetwork;
        _ipAddress = IPAddress.Parse(ipAdd);
        _ipEndPoint = new IPEndPoint(_ipAddress, port);
        _socket = new Socket(_addressFamily, _socketType, _protocolType);
        _socket.Connect(_ipEndPoint);
        return 0;
    }
    catch (Exception e)
    {
        return -1;
    }
}
public int Listen(string ipAdd, int port, ClientManager clientManager)
{
    try
    {
        _ipAddress = IPAddress.Parse(ipAdd);
        _ipEndPoint = new IPEndPoint(_ipAddress, port);
        _socket = new Socket(_addressFamily, _socketType, _protocolType);
        _socket.Bind(_ipEndPoint);
        while (_running)
        {
            _socket.Listen(30000);
            Socket socket = _socket.Accept();

            Thread thread = new Thread(() =>
            {
                ConnectionAccepted(ref socket, clientManager);
            });
            thread.Start();
        }
        return 0;
    }
    catch (Exception e)
    {
        return -1;
    }
}

private void ConnectionAccepted(ref Socket socket, ClientManager clientManager)
{
    try
    {
        string command = "";
        do
        {
            byte[] len = new byte[4];
            socket.Receive(len); //receive length of command
            byte[] buffer = new byte[BitConverter.ToInt32(len, 0)];
            socket.Receive(buffer);
            command = Encoding.Unicode.GetString(buffer);
            if (command.Contains("LOGIN"))
                LoginServerSide(ref socket, clientManager);
            else if (command.Contains("REGISTER"))
                RegisterServerSide(socket, clientManager); 
        } while (!command.Contains("TERMINATE"));
        Close(socket);
    }
    catch (Exception ex)
    {

    }
}

public bool LoginClientSide(string username, string password)
 {
     if (_socket == null)
         return false;
     //send action
     byte[] login = Encoding.Unicode.GetBytes("LOGIN");
     _socket.Send(BitConverter.GetBytes(login.Length));
     _socket.Send(login);
     byte[] ok = new byte[4];
     _socket.Receive(ok);
     if (Encoding.Unicode.GetString(ok) == "OK")
     {
         //send username
         byte[] usernameBytes = Encoding.Unicode.GetBytes(username);
         _socket.Send(usernameBytes);
         ok = new byte[40];
         _socket.Receive(ok); //OK: salt_value
         if (Encoding.Unicode.GetString(ok).Split(':').First() == "OK")
         {
             //get salt
             byte[] saltBytes = Encoding.Unicode.GetBytes(Encoding.Unicode.GetString(ok).Split(':').Last());
             //send hashed password
             byte[] passwordBytes = Encoding.Unicode.GetBytes(password);
             byte[] hashedPassword = CreateHashedPassword(passwordBytes, saltBytes);
             _socket.Send(hashedPassword);
             _socket.Receive(ok);
             if (Encoding.Unicode.GetString(ok) == "OK")
                 return true;
         }
     }
     return false;
 }

 private void LoginServerSide(ref Socket socket, ClientManager clientManager)
 {
     byte[] ok = Encoding.Unicode.GetBytes("OK");
     byte[] err = Encoding.Unicode.GetBytes("ER");
     //response to action
     _socket.Send(ok);
     //receive username
     byte[] buffer = new byte[50];
     socket.Receive(buffer);
     string username = Encoding.Unicode.GetString(buffer);
     //check for existing user
     if (clientManager.CheckForUser(username))
     {
         //user exists send OK: salt_value
         byte[] salt = clientManager.GetSalt(username);
         socket.Send(Encoding.Unicode.GetBytes("OK: " + salt));
         //receive hashed password
         buffer = new byte[64];
         socket.Receive(buffer);
         byte[] hashedPassword = clientManager.GetHashedPassword(username);
         if (buffer.SequenceEqual(hashedPassword))
         {
             //password is ok
             socket.Send(ok);
         }
         socket.Send(err);
     }
     //user does not exist
     socket.Send(err);
 }

public KeyValuePair<byte[], long> RegisterClientSide(string username, string password)
{
    if (_socket == null)
        throw new Exception("Socket not initialized");
    byte[] register = Encoding.Unicode.GetBytes("REGISTER");
    _socket.Send(BitConverter.GetBytes(register.Length));
    _socket.Send(register);
    byte[] ok = new byte[4];
    _socket.Receive(ok);
    string tmp = Encoding.Unicode.GetString(ok);
    if (tmp == "OK")
    {
        //send username
        byte[] usernameBytes = Encoding.Unicode.GetBytes(username);
        _socket.Send(usernameBytes);
        ok = new byte[4];
        _socket.Receive(ok);
        if (Encoding.Unicode.GetString(ok) == "OK")
        {
            //generate and send salt
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            byte[] salt = new byte[16];
            rng.GetNonZeroBytes(salt);
            _socket.Send(salt);
            _socket.Receive(ok);
            if (Encoding.Unicode.GetString(ok) == "OK")
            {
                //send hashed password
                byte[] passwordBytes = CreateHashedPassword(Encoding.Unicode.GetBytes(password), salt);
                _socket.Send(passwordBytes);
                _socket.Receive(ok);
                if (Encoding.Unicode.GetString(ok).Split(':').First() == "OK")
                {
                    byte[] idBytes = new byte[8];
                    _socket.Receive(idBytes);
                    long id = BitConverter.ToInt64(idBytes, 0);
                    //created new user
                    return new KeyValuePair<byte[], long>(salt, id);
                }
                //server error
            }
            //server error
        }
        //username exists
    }
    return new KeyValuePair<byte[], long>();
}

private void RegisterServerSide(Socket socket, ClientManager clientManager)
{
    byte[] ok = Encoding.Unicode.GetBytes("OK");
    byte[] err = Encoding.Unicode.GetBytes("ER");
    //response to action
    socket.Send(ok);
    //receive username
    byte[] buffer = new byte[50];
    socket.Receive(buffer);
    string username = Encoding.Unicode.GetString(buffer).TrimEnd('\0');
    //check for existing user
    if (!clientManager.CheckForUser(username))
    {
        //user does not exist send ok
        socket.Send(ok);
        //receive salt
        buffer = new byte[16];
        socket.Receive(buffer);
        //save salt
        byte[] salt = new byte[16];
        buffer.CopyTo(salt, 0);
        //send ok
        socket.Send(ok);
        //receive hashed password
        buffer = new byte[64];
        socket.Receive(buffer);
        //save hashed password
        byte[] pass = new byte[64];
        buffer.CopyTo(pass, 0);
        //send ok: id
        long id = clientManager.CreateNewUser(username, pass, salt);
        socket.Send(Encoding.Unicode.GetBytes("OK"));
        socket.Send(BitConverter.GetBytes(id));
    }
    else
        socket.Send(err);
}
}
在服务器端:

Authentication _auth = new Authentication(SocketType.Stream, AddressFamily.InterNetwork, ProtocolType.Tcp);
_auth.Listen(_IPAddress, _port, this);
因此,从这里您可以看到,我对连接客户机到服务器执行了相同的过程,但在一种情况下,这个过程通过了,而在另一种情况下(登录)失败了。 IP地址是我的本地IP,端口是30012。
欢迎任何帮助。

我已经找到了我的错误所在。在首次发送“OK”时的LoginServerSide函数中,我使用了侦听套接字(_socket)而不是在accept(socket)上创建的工作套接字。

为什么不检查来自
Connect()
的失败结果?您应该检查它是否返回-1。事实上,您最好只处理异常,因为-1没有告诉您为什么它无法连接。另外,既然已经在构造函数中设置了
\u addressFamily
,为什么还要在
Connect()
中设置它?您这样做完全忽略了传递给构造函数的参数。@Connect()中的itsme86设置_addressFamily来自我忘记删除的旧版本代码。在任何情况下,我都在使用互联网。关于例外情况,我只是缩短了本文的代码。我捕捉到了每一个可能的异常,现在它只给出了我提到的一个。为什么这个问题被标记为,当只有套接字相关的代码时??
Authentication _auth = new Authentication(SocketType.Stream, AddressFamily.InterNetwork, ProtocolType.Tcp);
_auth.Connect(_serverIPAdd, _port);
bool login = _auth.LoginClientSide(login.textBox.Text, login.textBox1.Text)
Authentication _auth = new Authentication(SocketType.Stream, AddressFamily.InterNetwork, ProtocolType.Tcp);
_auth.Listen(_IPAddress, _port, this);