【问题标题】:when client is closed server crash当客户端关闭服务器崩溃
【发布时间】:2015-11-17 00:18:35
【问题描述】:

当我从客户端连接到服务器时出现问题,它连接没有任何问题,但是当我关闭客户端窗口时,服务器显示以下错误消息:

The length can not be less than zero. Parameter name: length

然后当我尝试重新连接客户端时它也崩溃了

这是服务器源代码:

    serverSocket.Start()
    AddInfo("Server Started", ConsoleColor.Cyan)

    AddInfo("---------------- ACCOUNTS ----------------", ConsoleColor.Blue)
    Dim AN As Integer = 0
    For Each f In Directory.GetFiles("saved\accounts\")
        Dim acc As String = Path.GetFileNameWithoutExtension(f).Split(CChar("%"))(0)
        Dim pass As String = Path.GetFileNameWithoutExtension(f).Split(CChar("%"))(1)
        AddInfo(acc & " - " & pass, ConsoleColor.Magenta)
        AN += 1
    Next
    AddInfo(AN & " Accounts exists .", ConsoleColor.DarkCyan)
    AddInfo("-----------------------------------------------", ConsoleColor.Blue)

    clientSocket = serverSocket.AcceptTcpClient()
    AddInfo("New Client Connected", ConsoleColor.Yellow)
    clients_number += 1
    AddInfo("Clients Num : " & clients_number, ConsoleColor.DarkYellow)
    requestCount = 0

    While (True)
        'RECEIVING
        requestCount = requestCount + 1
        serverStream = clientSocket.GetStream()
        Dim bytesFrom(10024) As Byte
        serverStream.Read(bytesFrom, 0, CInt(clientSocket.ReceiveBufferSize))
        Dim dataFromClient As String = System.Text.Encoding.ASCII.GetString(bytesFrom)
        dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"))
        AddInfo("Data from client -  " + dataFromClient, ConsoleColor.DarkYellow)

        '### CHEKING ACCOUNT ###
        For Each f In Directory.GetFiles("saved\accounts\")
            If dataFromClient = Path.GetFileNameWithoutExtension(f) Then
                account_avaible = True
            End If
        Next
        If account_avaible = True Then
            Dim serverResponse As String = ""
            Dim l As New List(Of String)
            l.AddRange(File.ReadAllLines("saved\accounts\" & dataFromClient & ".inf"))
            For i = 0 To l.Count - 1
                serverResponse += l.Item(i).ToString.Split(CChar("="))(1) & "|"
            Next
            Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(serverResponse)
            serverStream.Write(sendBytes, 0, sendBytes.Length)
            serverStream.Flush()
            AddInfo(serverResponse, ConsoleColor.Green)
        Else
            Dim serverResponse As String = "connection_false"
            Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(serverResponse)
            serverStream.Write(sendBytes, 0, sendBytes.Length)
            serverStream.Flush()
            AddInfo(serverResponse, ConsoleColor.Green)
            account_avaible = False
        End If
    End While

【问题讨论】:

  • 无错误处理。不是一个。我从来没有做过任何 vb.net 开发,但如果我不得不猜测,我会说你的问题从这里开始:serverStream.Read(bytesFrom, 0, CInt(clientSocket.ReceiveBufferSize))。可能,clientSocket.ReceiveBufferSize 是否定的,表示发生了一些错误。您需要进行错误处理并确保不会以负长度调用 serverStream.Read()(这显然是正在发生的事情)。有 vb.net 经验的人可能会对此有所了解,但我将从那里开始。
  • 我猜在某个时候当它关闭时,客户端会发送一个不带“$”的字符串,然后dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$")) 这行会崩溃,因为dataFromClient.IndexOf("$") 返回-1,因为没有“ $"
  • 如果我删除 $ 服务器会出错
  • 当您关闭客户端时,while(true) 循环会导致服务器尝试从不再存在的流中读取。 clientSocket = serverSocket.AcceptTcpClient() 行会阻塞,直到建立连接,这就是为什么它在客户端连接之前不会崩溃,但是当客户端断开连接时它已经在循环中。在每次从流中读取之前检查有效连接。
  • 至于当您尝试重新连接时客户端也会崩溃,当然会。不再有服务器监听它连接。将您的服务器流读取放入 try catch 块和您的客户端代码中,与上面@FilipeGonçalves 的 cmets 一致。

标签: vb.net sockets tcp server client


【解决方案1】:

我已经解决了这个问题。谢谢@WDS。 我删除了循环并返回到clientSocket = serverSocket.AcceptTcpClient()

这是来源:

`serverSocket.Start() : AddInfo("服务器启动", ConsoleColor.Cyan)

    AddInfo("---------------- ACCOUNTS ----------------", ConsoleColor.Blue)
    Dim AN As Integer = 0
    For Each f In Directory.GetFiles("saved\accounts\")
        Dim acc As String = Path.GetFileNameWithoutExtension(f).Split(CChar("%"))(0)
        Dim pass As String = Path.GetFileNameWithoutExtension(f).Split(CChar("%"))(1)
        AddInfo(acc & " - " & pass, ConsoleColor.Magenta)
        AN += 1
    Next
    AddInfo(AN & " Accounts exists .", ConsoleColor.DarkCyan)
    AddInfo("-----------------------------------------------", ConsoleColor.Blue)

渡渡鸟:

    account_avaible = False
    clientSocket = serverSocket.AcceptTcpClient()
    AddInfo("New Client Connected", ConsoleColor.Yellow)
    clients_number += 1
    AddInfo("Clients Num : " & clients_number, ConsoleColor.DarkYellow)
    requestCount = 0

        'RECEIVING
        requestCount = requestCount + 1
        serverStream = clientSocket.GetStream()
        Dim bytesFrom(10024) As Byte
        serverStream.Read(bytesFrom, 0, clientSocket.ReceiveBufferSize)
        Dim dataFromClient As String = System.Text.Encoding.ASCII.GetString(bytesFrom)
        dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"))
        AddInfo("Data from client -  " + dataFromClient, ConsoleColor.DarkYellow)

        '### CHEKING ACCOUNT ###
        For Each f In Directory.GetFiles("saved\accounts\")
            If dataFromClient = Path.GetFileNameWithoutExtension(f) Then
                account_avaible = True
            End If
        Next
        If account_avaible = True Then
            Dim serverResponse As String = ""
            Dim l As New List(Of String)
            l.AddRange(File.ReadAllLines("saved\accounts\" & dataFromClient & ".inf"))
            For i = 0 To l.Count - 1
                serverResponse += l.Item(i).ToString.Split(CChar("="))(1) & "|"
            Next
            Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(serverResponse)
            serverStream.Write(sendBytes, 0, sendBytes.Length)
            serverStream.Flush()
            AddInfo(serverResponse, ConsoleColor.Green)
        Else
            Dim serverResponse As String = "connection_false"
            Dim sendBytes As [Byte]() = Encoding.ASCII.GetBytes(serverResponse)
            serverStream.Write(sendBytes, 0, sendBytes.Length)
            serverStream.Flush()
            AddInfo(serverResponse, ConsoleColor.Green)
            account_avaible = False
    End If

    GoTo Dodo

    'clientSocket.Close()
    'serverSocket.Stop()`

但现在我遇到了新问题 =/ 当我输入了错误的帐户消息显示(“错误帐户”),然后当我尝试输入其他帐户时,客户端出现错误(冻结)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    • 2011-06-15
    • 1970-01-01
    • 2019-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多