2009-03-26 3 views
0

Обратите внимание, что вопрос заключается в использовании асинхронного режима обратного вызова только на сокетах!TCP-клиент Обратный вызов асинхронного сокета

Я хочу создать TCP-клиент, который уведомит меня, когда пакет будет получен, и когда я сокет закрывается, потому что функции, предлагаемые NET с beginRecv, endRecv не сообщает, доступно ли соединение.

Мой вопрос: Не существует способа создать клиент TCP так же, как с помощью WinAPI?

Я имею в виду вызов WSAAsyncSelect с сообщением, когда сообщение получено, оно вызывает функцию, которую вы вызывали в WSAAsyncSelect, а затем вы можете увидеть, закрыто ли соединение или есть новый пакет через WP_Admin FD_CLOSE FD_READ FD_WRITE.

Если это не так. Я не могу контролировать соединение и входящие пакеты одновременно? Я не хочу постоянно называть BeginRecv EndRecv. -.-

Заранее благодарен!

+0

Нужно ли быть асинхронным, или вы можете сделать поточную версию, которая делает то, что вы хотите? – sfossen

+0

Это клиент или сервер? Вы слушаете или подключаетесь? – sfossen

ответ

1

Если передать объект состояния, который включает в себя ссылку на ваш сокет, вы будете иметь доступ к самой розетке.

public class SocketState 
{ 
    public SocketState(Socket s) 
    { 
    this._socket = s; 
    } 

    private Socket _socket; 
    public Socket Socket 
    { 
    get{return _socket;} 
    } 
} 


void SomeFunction() 
{ 
//do some stuff in your code 

SocketState stateObject = new SocketState(mySocket); 
mySocket.BeginReceive(buffer, offset, size, flags, CallBack, stateObject); 
//do some other stuff 
} 

public void CallBack(IAsyncResult result) 
{ 
    SocketState state = (SocketState)result.AsyncState; 
    state.Socket.EndReceive(result); 

    //do stuff with your socket. 
    if(state.Socket.Available) 
    mySocket.BeginReceive(buffer, offset, size, flags, CallBack, state); 
} 
1

Ваш вопрос не совсем ясен. Тоном вашего вопроса кажется, что вы не хотите делать какую-либо дополнительную работу. Вы не можете выполнять асинхронную работу без дополнительной работы.

Лучшим подходом является использование асинхронного API от Microsoft с использованием BeginReceive/EndReceive. Они вызовут ваши обратные вызовы, когда сокет будет закрыт. Однако вы не можете легко использовать поддержку IO Stream в .NET, делая это, поэтому есть дополнительная работа.

Если вы хотите большего контроля, вам нужно сделать больше работы. Вот и все.

+0

@Mystere Man, когда я вызываю BeginDisconnect, он отключает меня, в то время как я ожидаю, что программа выполнит обратный вызов, когда сокет будет отключен сервером. Я чувствую себя хорошо с BeginRecv, EndRecv, но он не сообщает мне, если соединение все еще живое. Вот почему я так зол. Не могли бы вы предоставить решение –

+0

Он не должен уведомлять вас, если соединение живое, ему нужно только уведомить вас, когда соединение мертво. EndReceive делает это, возвращая исключение или 0 байтов. –

0

Вы также можете написать простую резьбовую версию для контроля сокета и дать вам события и вызвать обратные вызовы.

Server type code

Simple Socket code