На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Асинхронный socket c#
    Создаю асинхронный сокет, после получения пакета он подвисает и, похоже, ждет еще пакетов:
    Socket connected to 205.188.251.43:5190
    Received 10 bytes from server
    ...
    Как сделать чтобы он продолжал работу, а не подвисал (но при этом, если действительно придут данные, он их получил)?

    ExpandedWrap disabled
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Net;
      using System.Net.Sockets;
      using System.Threading;
       
      namespace ConsoleApplication1 {
       
          class Program {
              static void Main(string[] args) {
                  new Program();
              }
       
              public Program() {
                  SimpleClient client = new SimpleClient();
                  client.start();
              }
          }
       
          class SimpleClient {
       
              private static ManualResetEvent connectDone =
                  new ManualResetEvent(false);
              private static ManualResetEvent sendDone =
                  new ManualResetEvent(false);
              private static ManualResetEvent receiveDone =
                  new ManualResetEvent(false);
       
              private static string response = string.Empty;
       
              byte[] bf = new byte[1024];
       
              public void start() {
                  IPHostEntry ipHostInfo = Dns.GetHostEntry("login.icq.com");
                  IPAddress ipAdress = ipHostInfo.AddressList[0];
                  IPEndPoint remoteEP = new IPEndPoint(ipAdress, 5190);
       
                  Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
       
                  sock.BeginConnect(remoteEP, new AsyncCallback(ConnectCallBack), sock);
                  connectDone.WaitOne();
       
                  BeginReceive(sock);
                  receiveDone.WaitOne();
       
                  Send(sock, "test");
                  sendDone.WaitOne();
       
                  sock.Shutdown(SocketShutdown.Both);
                  sock.Close();
              }
       
              void BeginReceive(Socket sock) {
                  try {
                      StateObject so = new StateObject();
                      so.workSocket = sock;
       
                      sock.BeginReceive(so.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), so);
                  } catch (Exception e) {
                      Console.WriteLine("Error occured: {0}", e.Message);
                  }
              }
       
              void ReceiveCallback(IAsyncResult ar) {
                  try {
                      StateObject so = (StateObject)ar.AsyncState;
                      Socket sock = so.workSocket;
       
                      int bytesRead = sock.EndReceive(ar);
       
                      Console.WriteLine("Received {0} bytes from server", bytesRead);
       
                      if (bytesRead > 0) {
                          so.sb.Append(Encoding.ASCII.GetString(so.buffer, 0, bytesRead));
                          sock.BeginReceive(so.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), so);
                      } else {
                          if (so.sb.Length > 1) {
                              response = so.sb.ToString();
                          }
                          receiveDone.Set();
                      }
                  } catch (Exception e) {
                      Console.WriteLine("Error occured: {0}", e.Message);
                  }
              }
       
              void ConnectCallBack(IAsyncResult ar) {
                  try {
                      Socket s = (Socket)ar.AsyncState;
                      s.EndConnect(ar);
       
                      Console.WriteLine("Socket connected to {0}", s.RemoteEndPoint.ToString());
       
                      connectDone.Set();
       
                  } catch (Exception e) {
                      Console.WriteLine("Error occured: {0}", e.Message);
                  }
              }
       
              void Send(Socket sock, string data) {
                  byte[] byteData = Encoding.ASCII.GetBytes(data);
       
                  sock.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallBack), sock);
       
              }
       
              void SendCallBack(IAsyncResult ar) {
                  try {
                      Socket sock = (Socket)ar.AsyncState;
       
                      int bytesSent = sock.EndSend(ar);
       
                      Console.WriteLine("Sent {0} bytes to server", bytesSent);
       
                      sendDone.Set();
       
                  } catch (Exception e) {
                      Console.WriteLine("Error occured: {0}", e.Message);
                  }
              }
       
              public class StateObject {
                  // Client socket.
                  public Socket workSocket = null;
                  // Size of receive buffer.
                  public const int BufferSize = 256;
                  // Receive buffer.
                  public byte[] buffer = new byte[BufferSize];
                  // Received data string.
                  public StringBuilder sb = new StringBuilder();
              }
       
          }
      }
      Используй TcpClient
        referee
        во первых, давай определимся какая именно функциональность тебе требуется.
        во вторых,
        Цитата referee @

        BeginReceive(sock);
        receiveDone.WaitOne();

        Send(sock, "test");
        sendDone.WaitOne();

        почитай про System.Threading..::.WaitHandle.WaitOne()
        Цитата
        Блокирует текущий поток до получения сигнала объектом WaitHandle.

        в третьих
        Цитата referee @
        IPHostEntry ipHostInfo = Dns.GetHostEntry("login.icq.com");

        неудачный пример, на твоем месте я бы сначала попробовал на локальном сервисе
          Цитата Отшельник @
          во первых, давай определимся какая именно функциональность тебе требуется.

          Не случайно в примере указан адрес "login.icq.com".
          Цитата Отшельник @
          почитай про System.Threading..::.WaitHandle.WaitOne()

          Я поэтому и хотел узнать каким образом работают с сокетами и каким образом прервать это ожидание, т.к. до
          Цитата
          receiveDone.Set();
          не доходит.
          Цитата Отшельник @
          неудачный пример, на твоем месте я бы сначала попробовал на локальном сервисе

          Есть принципиальные различия, кроме структуры протокола?
            Цитата referee @
            Я поэтому и хотел узнать каким образом работают с сокетами и каким образом прервать это ожидание, т.к. до

            закомментируй вызов
            Цитата referee @

            sendDone.WaitOne();
            receiveDone.WaitOne();


            Цитата referee @
            Есть принципиальные различия, кроме структуры протокола?

            нет. просто сможешь четко взаимодействовать с частями приложениях, а в случае
            с
            Цитата Отшельник @
            Dns.GetHostEntry("login.icq.com");

            одна из сторон - для тебя "черный ящик"
              Спасиб, попробую.
              Цитата Отшельник @
              закомментируй вызов

              Но как быть если я получил пакет, обработал его - отправил свой пакет, как получить снова ответ от сервера? Если программа уже выполнится.
                Цитата referee @
                Но как быть если я получил пакет, обработал его - отправил свой пакет, как получить снова ответ от сервера?

                ExpandedWrap disabled
                  while(true)
                  {
                  BeginReceive(sock);
                  ...
                   
                  Send(sock, "test");
                  ...
                  }
                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                0 пользователей:


                Рейтинг@Mail.ru
                [ Script execution time: 0,0306 ]   [ 15 queries used ]   [ Generated: 17.05.24, 11:30 GMT ]