Async Socket Problem

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • MehdiMAX
    New Member
    • Jun 2013
    • 4

    Async Socket Problem

    Hi.
    I'm creating the LAN messenger (Client/Server) application using Async Socket Method based on MSDN Examples.
    First I've created a Common Library including two Classes: Server and Client (because of some similar parts in both of them I preferred to create a Single Shared Class). Then made two windows form applications Client and Server,includin g that Library. Server starts listening and in the Client Main form when clicking on the "Connect Button",it connects successfully to the Server. Then with clicking on Disconnect Button, the client disconnected successfully. But My Problem Begins when I try to connect again, by throwing this Exception: "Only one usage of each socket address (protocol/network address/port) is normally permitted".
    The point is that when I try to debug the client step by step slowly, it never throws that exception but when I step faster or Run without debugging, that error appears!!!
    After tracing through the code, I've found that the error rises when calling "socket.EndConn ect()"
    Please Help Me.
    Here is My Snippet Codes:
    Code:
    (Client Class):
    class ClientSocket{
    ...
    public bool IsConnected(Socket client, int PollingTime)
    {
    return !(client.Poll(PollingTime, SelectMode.SelectRead) &&client.Available == 0);
    }
    
    public void Connect(EndPoint _remoteEP)
    {
    if (!IsConnected(this.client_Socket,pollingTime))
    {
    try{
    client_Socket.BeginConnect(_remoteEP, newAsyncCallback(ConnectCallBack), client_Socket);
    connectDone.WaitOne();
    }
    catch{
    client_Socket.Shutdown(SocketShutdown.Both);
    client_Socket.Disconnect(true);
    connectDone.Reset();
    }
     }
    else{…}
    }
    
    private void ConnectCallBack(IAsyncResultar){
    StateObject state = newStateObject();
    try{
    Socket client = (Socket)ar.AsyncState;
    state.workSocket = client;
    client.EndConnect(ar);
    client.BeginReceive(state.buffer,0,StateObject.BufferSize,SocketFlags.None,newAsyncCallback(ReceiveCallback),state);
    connectDone.Set();
    }
    catch (Exception ex){
    ...		
    }
    finally {... }
    }
    
    public void Disconnect()
    {
    try{
    disconnectDone.Reset();
      try {
      client_Socket.Shutdown(SocketShutdown.Both);
      client_Socket.BeginDisconnect(true, newAsyncCallback(DisconnectCallback), client_Socket);
      ShowMessage("Disconnecting.....");
      disconnectDone.WaitOne();
      if (!client_Socket.Connected) {
        ShowMessage("Disconnected!");
      }
    }
    catch{}
    }
    
    private void DisconnectCallback(IAsyncResultar)
    {
    Socket client = (Socket)ar.AsyncState;
    client.EndDisconnect(ar);
    disconnectDone.Set();
    }
    ...
    }
    =============================
    
    In Main Client Form Application:
    
    {
    ...
    
    ClientSocket cilentSock=new ClientSocket();
    
    private void buttonConnect_Click(object sender, EventArgs e)
    {
    buttonConnect.Enabled = false;
    buttonDisconnect.Enabled = true;
    int port = Int32.Parse(textBoxRemotePort.Text);
    ServerEP = newIPEndPoint(IPAddress.Parse(textBoxRemoteAddress.Text), port);
    clientSock.SetRemoteEP(ServerEP);
    try{
    clientSock.Connect(ServerEP);
    }
    catch {…}
    finally{…}
    }
    
    private void buttonDisconnect_Click(object sender, EventArgs e)
    {
    try{
    clientSock.Disconnect();
    }
    catch(Exception ex){…}
    }
    ...
    }
  • Oralloy
    Recognized Expert Contributor
    • Jun 2010
    • 988

    #2
    MehdiMAX,

    Why is the only place you do a Shutdown in the Connect method?

    Kind Regards,
    Oralloy

    Comment

    • MehdiMAX
      New Member
      • Jun 2013
      • 4

      #3
      Hi Oralloy, thanks for your notice. I removed the shutdown command in the connect catch block,and just call the disconnect method. But it's not solved the problem. It happens when connecting after one disconnect operation.(on the client.EndConne ct call in the ConnectCallback method ).

      Comment

      • Oralloy
        Recognized Expert Contributor
        • Jun 2010
        • 988

        #4
        MehdiMAX,

        My bad. Sorry about that.

        Are you seeing the "Disconnect ed" message when your error case arises?

        Oralloy

        Comment

        • MehdiMAX
          New Member
          • Jun 2013
          • 4

          #5
          When I disconnect manually it shows the "Disconnecting" and "Disconnect ed" messages truely. but when I try to connect again, before any messages, that error appears, also the the client.Connecte d value is false.

          Comment

          • Oralloy
            Recognized Expert Contributor
            • Jun 2010
            • 988

            #6
            MehdiMAX,

            One easy solution you might use in your client software is to create a new ClientSocket object for each new connection.

            Will that work?

            I inow that it doesn't address the root cause of the problem, but it will let you progress forward with the project.

            Kind Regards,
            Oralloy

            Comment

            • MehdiMAX
              New Member
              • Jun 2013
              • 4

              #7
              Great! The problem solved. I've updated the code with your advise and it works great.Thank you so much!
              Here is my updated snippet code:
              Code:
              class ClientSocket{
              ...
              public bool IsConnected(Socket client, int PollingTime)
              {
                return !(client.Poll(PollingTime, SelectMode.SelectRead) &&client.Available == 0);
              }
              
              public void Connect(EndPoint _remoteEP)
              {
              [B]Socket clientsock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);[/B]
                clientsock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
                if (!IsConnected(this.client_Socket, pollingTime))
                {
                  this.client_Socket = clientsock;
                  try{
                     client_Socket.BeginConnect(_remoteEP, new AsyncCallback(ConnectCallBack), client_Socket);
                     connectDone.WaitOne(pollingTime);
                  }
                  catch{
                         client_Socket.Disconnect(true);
                         connectDone.Reset();
                  }
                 }
                 else{
                   return (!IsConnected(client_Socket, pollingTime));
                 }
              }
              
              private void ConnectCallBack(IAsyncResultar){
              StateObject state = newStateObject();
              try{
              Socket client = (Socket)ar.AsyncState;
              state.workSocket = client;
              client.EndConnect(ar);
              client.BeginReceive(state.buffer,0,StateObject.BufferSize,SocketFlags.None,newAsyncCallback(ReceiveCallback),state);
              connectDone.Set();
              }
              catch (Exception ex){
              ...		
              }
              finally {... }
              }
              
              public void Disconnect()
              {
              try{
              disconnectDone.Reset();
                try {
                client_Socket.Shutdown(SocketShutdown.Both);
                client_Socket.BeginDisconnect(true, newAsyncCallback(DisconnectCallback), client_Socket);
                ShowMessage("Disconnecting.....");
                disconnectDone.WaitOne();
                if (!client_Socket.Connected) {
                  ShowMessage("Disconnected!");
                }
              }
              catch{}
              }
              
              private void DisconnectCallback(IAsyncResultar)
              {
              Socket client = (Socket)ar.AsyncState;
              client.EndDisconnect(ar);
              disconnectDone.Set();
              }
              ...
              }
              =============================
              
              In Main Client Form Application:
              
              {
              ...
              
              ClientSocket cilentSock=new ClientSocket();
              
              private void buttonConnect_Click(object sender, EventArgs e)
              {
              buttonConnect.Enabled = false;
              buttonDisconnect.Enabled = true;
              int port = Int32.Parse(textBoxRemotePort.Text);
              ServerEP = newIPEndPoint(IPAddress.Parse(textBoxRemoteAddress.Text), port);
              clientSock.SetRemoteEP(ServerEP);
              try{
              clientSock.Connect(ServerEP);
              }
              catch {…}
              finally{…}
              }
              
              private void buttonDisconnect_Click(object sender, EventArgs e)
              {
              try{
              clientSock.Disconnect();
              }
              catch(Exception ex){…}
              }
              ...
              }
              Thanks again.

              Comment

              • Oralloy
                Recognized Expert Contributor
                • Jun 2010
                • 988

                #8
                Glad to hear it, MehdiMAX!

                Rock On!

                Comment

                Working...