2013-01-08 6 views
1

현재 VB.Net에서 비동기 통신을 사용하는 파일 공유 응용 프로그램을 개발 중입니다. 필자는 클라이언트와 서버 간의 간단한 연결을 코딩했습니다. 하지만, 현재 클라이언트와 서버 모두를위한 분리 서브 루틴을 수행하는 데 시간이 많이 걸리고 있습니다. 나는 현재 며칠 동안이 문제에 갇혀 있으며 분리 작업을 수행하는 좋은 방법을 찾을 수 없기 때문에 여기에서 도움을 요청하기로 결정했습니다. 나는 정지 버튼을 누를 때 나는 서버에서 모든 클라이언트의 연결을 해제하려면,비동기 연결을 적절하게 연결 해제하고 다시 연결

서버 응용 프로그램 서버 부분에

Private Sub FileSharingInitialize() 

    ServerSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) 

    Dim EndPoint As IPEndPoint = New IPEndPoint(IPAddress.Any, 7777) 

    ServerSocket.Bind(EndPoint) 

    ServerSocket.Listen(0) 

End Sub 


Private Sub FileSharingOnAccept(ByVal AsyncResult As IAsyncResult) 

    ClientSocket = ServerSocket.EndAccept(AsyncResult) 

    FileSharingAddClient(ClientSocket) 

    ClientSocket.BeginReceive(ByteData, 0, ByteData.Length, SocketFlags.None, New AsyncCallback(AddressOf FileSharingOnReceive), ClientSocket) 

End Sub 


Delegate Sub _FileSharingAddClient(ByVal Client As Socket) 


Private Sub FileSharingAddClient(ByVal Client As Socket) 

    If InvokeRequired Then 

     Invoke(New _FileSharingAddClient(AddressOf FileSharingAddClient), Client) 

     Exit Sub 

    End If 

    lvConnectedClients.Items.Add("") 

    lvConnectedClients.Items(lvConnectedClients.Items.Count - 1).SubItems.Add(Client.LocalEndPoint.ToString) 

End Sub 


Private Sub FileSharingOnReceive(ByVal AsyncResult As IAsyncResult) 

    Dim Client As Socket = CType(AsyncResult.AsyncState, Socket) 

    Client.EndReceive(AsyncResult) 

    Dim ByteReceived As Byte() = ByteData 

    Dim LogMessage As String = System.Text.Encoding.ASCII.GetString(ByteReceived) 

    ReadLogMessage(LogMessage) 

End Sub 


Delegate Sub _ReadLogMessage(ByVal LogMessage As String) 


Private Sub ReadLogMessage(ByVal LogMessage As String) 

    If InvokeRequired Then 

     Invoke(New _ReadLogMessage(AddressOf ReadLogMessage), LogMessage) 

     Exit Sub 

    End If 

    DisplayLogMessage(LogMessage) 

End Sub 


Private Sub DisplayLogMessage(ByVal Log As String) 

    Dim TimeStamp As String = "[" & DateAndTime.Now.ToString("hh:mm:ss tt dddd, dd MMMM yyyy") & "]: " 

    Dim LogMessage As String = "" 

    If txtLog.Text > "" Then 

     LogMessage = Chr(10) & Chr(13) 

    End If 

    LogMessage &= TimeStamp 

    LogMessage &= Log 

    txtLog.SelectionStart = Len(txtLog.Text) 

    txtLog.SelectedText = LogMessage 

End Sub 


Private Sub frmMain_Load(sender As Object, e As System.EventArgs) Handles Me.Load 

    FileSharingInitialize() 

End Sub 


Private Sub btnStart_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles btnStart.MouseClick 

    ServerSocket.BeginAccept(New AsyncCallback(AddressOf FileSharingOnAccept), Nothing) 

    DisplayLogMessage("Server started." & Environment.NewLine) 

End Sub 

:

여기 내 코드입니다. 내 시작 버튼에서이 코드를 시도했지만 작동하지 않습니다. 소켓이 연결되어 있지 않다는 오류가 표시됩니다. 서버 응용 프로그램에 ClientSocket이라는 소켓이 있으므로 잘못된 소켓의 연결을 끊는 것이 좋습니다. 아니면 클라이언트 연결을 끊기 위해 루프를 사용해야합니까? 어떻게 생각해?

Private Sub btnStop_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles btnStop.MouseClick 

    ServerSocket.Shutdown(SocketShutdown.Both) 

    ServerSocket.Close() 

    ServerSocket = Nothing 

End Sub 

클라이언트 응용 프로그램

Private Sub btnConnect_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles btnConnect.MouseClick 

    ClientSocket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) 

    Dim Address As IPAddress = IPAddress.Parse(frmNetworkSettings.txtServerIPAddress.Text) 

    Dim Endpoint As IPEndPoint = New IPEndPoint(Address, CInt(frmNetworkSettings.txtFileSharingPort.Text)) 

    ClientSocket.BeginConnect(Endpoint, New AsyncCallback(AddressOf FileSharingOnConnect), Nothing) 

    SendLogMessage(Username & " is connected." & Environment.NewLine, ClientSocket) 

End Sub 


Private Sub FileSharingOnConnect(ByVal AsyncResult As IAsyncResult) 

    ClientSocket.EndConnect(AsyncResult) 

End Sub 


Private Sub SendLogMessage(ByVal LogMessage As String, ByVal Client As Socket) 

    Dim SendByteData As Byte() = System.Text.Encoding.ASCII.GetBytes(LogMessage) 

    Client.BeginSend(SendByteData, 0, SendByteData.Length, SocketFlags.None, New AsyncCallback(AddressOf OnSendLogMessage), Client) 

End Sub 


Private Sub OnSendLogMessage(ByVal AsyncResult As IAsyncResult) 

    Dim Client As Socket = CType(AsyncResult.AsyncState, Socket) 

    Client.EndSend(AsyncResult) 

End Sub 

클라이언트 부분에 문제는 서버에서 동일합니다. 클라이언트와 서버의 연결을 끊는 코드가 작동하지 않습니다. 나중에 다시 연결할 때도 연결 해제 단추를 누른 후 서버에 로그를 보내지 않습니다. 소켓이 처리 된 것 같습니다. 그렇다면 어떻게해야 연결을 다시 시도 할 때 소켓을 재사용 할 수 없습니까? 또 다른 한가지는 서버를 시작하지 않고 연결 단추를 누른 후 서버를 시작하면 클라이언트가 연결된 서버로 로그가 전송된다는 것입니다. 문제는 서버의 수신 대기 방법에있는 것 같습니다. 나는 그 일이 일어나길 바라지 만, 클라이언트가 서버에 연결되어 있지 않다는 경고와 클라이언트가 연결 한 후에 서버에 로그 메시지를 보내지 않는 예외를 원한다. 정말 모르겠지만, 듣기 방법의 백 로그를 0으로 설정하면 그런 일이 일어나지 않을 것입니다.

미리 감사드립니다.

답변

0

더 나은 방법은 플래그 시스템을 구현하는 것입니다. 한 클라이언트 또는 서버가 다른 연결 끊기 플래그를 다른 쪽 끝으로 연결하려고 할 때 다른 쪽 끝에서 코드 단절을 이해할 수 있습니다.

+0

비동기 연결을 사용하는 것이 비동기식 연결을 사용하지 않으므로 멀티 스레딩을 사용하여 동기식 연결을 사용하여 시프트하기로 결정했습니다. 내 문제. 어쨌든, 시간과 대답에 감사드립니다. :) –