Я только начал изучать сокеты с помощью различных поисковых запросов Google, но у меня возникли проблемы с тем, чтобы понять, как правильно использовать сокеты в C #, и мне нужна помощь.
У меня есть тестовое приложение (Windows Forms) и другой класс (который на самом деле находится в его собственной .dll, но это не имеет значения) у меня есть весь код сервера / клиента для кода моих сокетов.
Вопрос 1)
В моем тестовом приложении на серверной части пользователь может нажать кнопку «начать прослушивание», и серверная часть моего приложения для сокетов должна начать прослушивать соединения по указанному адресу и порту, пока все хорошо.
Однако приложение будет заблокировано, и я ничего не могу сделать, пока кто-нибудь не подключится к серверу. Что делать, если никто не подключается? Как мне с этим справиться? Я мог бы указать тайм-аут приема, но что тогда? Выдает исключение, что мне с этим делать? Я бы хотел, чтобы в основном приложении выполнялась какая-то активность, чтобы пользователь знал, что приложение не зависло, и ждал подключения. Но если соединение не приходит, оно должно завершиться по таймауту и все закрыть.
Возможно, мне следует использовать асинхронные вызовы для отправки / получения методов, но они кажутся сбивающими с толку, и я не смог заставить его работать, только синхронная работа (я ' Я отправлю свой текущий код ниже.
Вопрос 2)
Нужно ли мне закрывать что-нибудь, когда истекает время ожидания отправки / получения вызова. Как вы увидите в моем текущем коде, у меня есть несколько закрытий сокета, но это почему-то кажется неправильным. Но также кажется неправильным, когда время операции истекает, и я не закрываю сокет.
В заключение двух моих вопросов ... Я бы хотел, чтобы приложение не блокировалось, чтобы пользователь знал сервер ожидает соединения (например, с небольшой анимацией). Если соединение не устанавливается по прошествии определенного периода времени, я хочу закрыть все, что должно быть закрыто. Когда соединение установлено или если оно не происходит по прошествии определенного периода времени, я хотел бы проинформировать основное приложение о результате.
Вот часть моего кода, остальное аналогично. Класс Packet
- это настраиваемый класс, который представляет мою настраиваемую единицу данных, на данный момент это просто набор свойств, основанных на перечислениях
, с методами преобразования их в байты и обратно в свойства.
Функция, которая начинает прослушивать соединения, выглядит примерно так:
public void StartListening(string address, int port) {
try {
byte[] bufferBytes = new byte[32];
if(address.Equals("0.0.0.0")) {
udpSocket.Bind(new IPEndPoint(IPAddress.Any, port));
} else {
udpSocket.Bind(new IPEndPoint(IPAddress.Parse(address), port));
}
remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
int numBytesReceived = udpSocket.ReceiveFrom(bufferBytes, ref remoteEndPoint);
if(numBytesReceived == 0) {
udpSocket.Close();
return;
}
Packet syncPacket = new Packet(bufferBytes);
if(syncPacket.PacketType != PacketType.Control) {
udpSocket.Close();
return;
}
} catch {
if(udpSocket != null) {
udpSocket.Close();
}
}
}
Я уверен, что у меня есть куча ненужного кода, но я новичок в этом и я не уверен, что делать, любая помощь в исправлении моего кода и способах решения вышеуказанных проблем действительно приветствуется.
РЕДАКТИРОВАТЬ:
Я, вероятно, должен был заявить, что мои требования заключаются в использовании UDP и реализации этих вещей я на прикладном уровне. Вы можете рассматривать это как домашнее задание, но я не помечен как таковой, потому что код не имеет значения и не будет частью моей оценки, а моя проблема (мой вопрос) заключается в том, «как кодировать», поскольку мой опыт работы с Sockets минимален, и это не так. учил.
Однако должен сказать, что я решил свою проблему, пока думаю ... Я использовал потоки в демонстрационном приложении, что доставляло мне некоторые проблемы, теперь я использую его в соединениях протокола, это имеет больше смысла, и я могу легко изменить свойства своего настраиваемого класса протокола и прочитать их из демонстрационного приложения.
Я указал тайм-аут и генерирую SocketException, если он достигает тайм-аута. При обнаружении такого исключения соединение сокета закрывается. Я говорю только о рукопожатии соединения, не более того. Если никаких исключений не обнаружено, код, вероятно, прошел гладко и соединение установлено.
Пожалуйста, измените свои ответы соответствующим образом. Сейчас мне не имеет смысла отмечать какой-либо из них как принятый ответ, надеюсь, вы понимаете.