Страница: 1 | 2 | 3 |
Вопрос: Дисконнект сокетов в .Net
Добавлено: 21.04.06 00:31
Автор вопроса: Neco | Web-сайт:
Ответы
Всего ответов: 38
Номер ответа: 31
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #31
Добавлено: 23.04.06 11:20
А меня, признаться, больше заинтересовало вот это:
Полазив по сети, нашел несколько примеров, но там это реализовано через AsyncOperation и SendOrPostCallback.. Как то все там запутано очень.. может всеже проще будет в поток передавать в конструкторе ссылку на объект синхронизации? и уже в потоке проверять invokerequred и по необходимости вызывать делегата?
А вообще.. вопрос.. ооочень интересный..
Номер ответа: 32
Автор ответа:
Neco
ICQ: 247906854
Вопросов: 133
Ответов: 882
Web-сайт:
Профиль | | #32
Добавлено: 23.04.06 13:07
Объект синхронизации - это форма? Я тоже к этому шёл, но потом отказался, т.к. при написании системных служб тебе никто не даст создавать окна.
Про AsyncOperation мне подсказали на gotdotnet - я попробовал - рульная штука. Всё очень коротко и понятно - старанно, что в msdn это забросили так, что не найдёшь (вообще там поиск дрянной).
Достаточно создать объект AsyncOperation и потом им вызвать Post((SendOrPostCallback) method, param).
В общем, в многопоточных классах теперь пользуюсь только им.
Счас пишу библиотеку для работы с сетью на манер старого родного винсока (всё-таки не въезжаю я в stream'ы - старая закалка даёт о себе знать). Делаю всё на чистых API. Обязательно попробую установить эту опцию, о результатах сюда чиркану.
Номер ответа: 33
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #33
Добавлено: 23.04.06 16:09
Да, именно форму я имел ввиду.. в принципе это может быть любой наследник Component, и мне тоже эта идея не очень понравилась..
Ну раз ты разобрался с этой бедой, то как теперь будет выглядеть твой пример класса(из этого топика) в свете полученных новый знаний?
Номер ответа: 34
Автор ответа:
Neco
ICQ: 247906854
Вопросов: 133
Ответов: 882
Web-сайт:
Профиль | | #34
Добавлено: 23.04.06 16:54
Класс:
Imports System.ComponentModel
Public Class clsMyClass
Public Event Event1(ByVal param As Integer)
Public Event Event2(ByVal param As Integer)
Dim w_asyncer As AsyncOperation
Private Sub AdapterEvent1(ByVal param As Object)
RaiseEvent Event1(CType(param, Integer))
End Sub
Private Sub AdapterEvent2(ByVal param As Object)
RaiseEvent Event2(CType(param, Integer))
End Sub
Public Sub New()
w_asyncer = AsyncOperationManager.CreateOperation(Nothing)
Dim thTmp As New Thread(AddressOf threda)
thTmp.Start()
End Sub
Private Sub threda()
w_asyncer.Post(CType(AddressOf AdapterEvent1, SendOrPostCallback), 555)
w_asyncer.Post(CType(AddressOf AdapterEvent2, SendOrPostCallback), 666)
End Sub
End Class
Ну и чтобы вам не мучаться, код формы:
Dim WithEvents foo As clsMyClass
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
foo = New clsMyClass
End Sub
Private Sub foo_Event1(ByVal param As Integer) Handles foo.Event1
ListBox1.Items.Add("Accept safe event 1. result = " + param.ToString)
End Sub
Private Sub foo_Event2(ByVal param As Integer) Handles foo.Event2
ListBox1.Items.Add("Accept safe event 2. result = " + param.ToString)
End Sub
End Class
Номер ответа: 35
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #35
Добавлено: 24.04.06 02:22
Neco, а вот это уже дело.. Респект!
Номер ответа: 36
Автор ответа:
Neco
ICQ: 247906854
Вопросов: 133
Ответов: 882
Web-сайт:
Профиль | | #36
Добавлено: 26.04.06 22:03
Там кое-какая обезьянка выскакивает - точно не уверен, но кажется, когда в обработчике события происходит ошибка, дебаггер не ставит точку останова на эту строку (т.е. нельзя, что-нить подправить и продолжить). Хотя может это из-за того, что событие вызывается из-под библиотеки.
2GSerg: Попробовал - keepalive не работает. Мож, я что-то не так делаю, но вот, что написано в MSDN:
An application can request that a TCP/IP provider enable the use of keep-alive packets on TCP connections by turning on the SO_KEEPALIVE socket option. A Windows Sockets provider need not support the use of keep-alives. If it does, the precise semantics are implementation-specific but should conform to section 4.2.3.6 of RFC 1122: Requirements for Internet Hosts—Communication Layers. If a connection is dropped as the result of keep-alives the error code WSAENETRESET is returned to any calls in progress on the socket, and any subsequent calls will fail with WSAENOTCONN.
Чё-та мне не нравится это
Ещё одна новость от педи-гри-пал: обрыв не регистрируется вообще НИКАКИМИ средствами - т.е. если у меня два компа подконнектятся и на одном я отключу сеть (прямо в винде, зайду и нажму "отключить", то на том компе, где я это сделал связь обовётся, а другой комп будет продолжать слать сообщения и в ус не дуть - send будет нагло возвращать количество отправленных байт (и net'овский socket ведёт себя также).
Это я говорю о неблокирующих сокетах - возможно, блокирующие лишены этой особенности и если send вернул 3, то можно голову давать на отсечение, что эти три байта дошли.
Плавно перехожу на совмещение этих двух видов в одном приложении, либо отказ от неблокирующих вовсе - но тогда надо для каждого клиента создавать по два потока (не жирно ли?) и напрочь забыть о событии Disconnected.
Короче, с сокетами творится одна большая беда!
Номер ответа: 37
Автор ответа:
EROS
Вопросов: 58
Ответов: 4255
Профиль | | #37
Добавлено: 27.04.06 01:02
Эт что же получается? что сокет шлет эти байты в никуда????? и даже в этом случае Connected все равно будет возвращать True?
Номер ответа: 38
Автор ответа:
Neco
ICQ: 247906854
Вопросов: 133
Ответов: 882
Web-сайт:
Профиль | | #38
Добавлено: 27.04.06 06:53
Не ну я конечно сильно надеюсь, что сделал что-то неправильно! Но факт, что этот код:
stdSock = New Sockets.TcpClient("192.168.88.128", 11200)
End Sub
Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
If stdSock IsNot Nothing Then
If stdSock.Connected Then
Dim buf() As Byte = System.Text.Encoding.Default.GetBytes(TextBox2.Text)
ListBox1.Items.Add("Std send result=" + stdSock.Client.Send(buf, buf.Length, Sockets.SocketFlags.None).ToString)
Else
MsgBox("Not connected!"
End If
End If
End Sub
ведёт себя именно так.
Т.е. я не понимаю тогда, что значит "tcp гарантирует передачу данных". Но самое главное, тогда я не понимаю, как можно что-то передать по сетке так, чтобы быть уверенным, что информация дошла и дошла лишь один раз (т.е. если отрицательный эффект от двойной передачи столь же велик как и от полной потери).