|
-
Jul 8th, 2004, 12:45 PM
#1
Thread Starter
Junior Member
-
Jul 9th, 2004, 12:58 PM
#2
Thread Starter
Junior Member
[B]Found one big answer on www.dotnet247.com
Read all below[\B]
I am trying to set up a socket so it will listen for any incomming UDP
packets. I have tried to call listen, but I get the error "Additional
information: The attempted operation is not supported for the type of object
referenced", almost like listen is not valid for UDP.
Socket socket = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
socket.Bind(new IPEndPoint(IPAddress.Any, 0));
socket.Listen(100);
The bind works, but the listen fails. If I don't do the listen, then if I
use poll I get nothing. Please help, I am pretty new at the whole UDP side
of things and I have already gone through the learning curve of making sure
you avoid UdpClient at all costs due to the limitations and bugs present in
that class.
Thanks.
Reply to this message...
Zane Thomas [.NET MVP]
On Wed, 3 Jul 2002 23:42:41 -0500, "Tyrel van Niekerk" <Click here to reveal e-mail address>
wrote:
>The bind works, but the listen fails.
Listen means "to listen for an incoming *connection* request" - but in UDP there
is no such thing as a connection. After the Bind all you need to do is use
ReceiveFrom or BeginReceiveFrom, I wouldn't waste my time trying to do anything
with Available.
I gave a presentation at a user's group on socket programming a while back. The
powerpoint slides and ten sample projects are at: www.abderaware.com, see the
Free Stuff folder.
--
*--------={ Fine Art for .NET }=--------*
| .Net Components @ www.abderaware.com |
*---------------------------------------*
Turn on, tune in, download.
zane a@t abderaware.com
Reply to this message...
Tyrel Van Niekerk
Cool, I found your examples. Just curious though, ReceiveFrom will wait
until it gets a message (block), so I guess you will have to set the
timeout for reading on the socket and then loop and try again until you
receive something. What I am doing here is sending requests to various
game servers to get info from them. Sometimes the servers don't respond
or the packet gets lost, so after a certain timeout period for each
server, I send the request again.
I am getting there though. I have it working now, but with one socket
per request, but that's because I did not use the ReceiveFrom, did not
think I could pass it the .Any address.
Thanks, on we go... :-)
*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Reply to this message...
Justin Richeson
This is the same type of thing I'm trying to do. I would like to create a program that can send UDP packets to a Half-Life game server with the specific command to have it send game/player data back to me. I have figured out how to send the data just fine using the UDPclient, but I've found that UDPclient's reviece mode is blocking. I would like to be able to create a program (or class) that can use the System.Net.Sockets to recieve a variable length UDP packet, but not have it block or set a timeout for the recieve so if nothing comes back the program doesn't just hang. Eventually this will be used as part of a program for a Character LCD Mod for my PC, but I'm trying to learn all of this stuff for future reference as well so if you have any tips, or a good location for sample code it would be appreciated...I keep trying MSDN stuff, but none of it ever wants to work.
P.S. I'm doing this in Visual Basic.NET, so VB.NET Code examples are the most helpful to me!
--Thanks all
--------------------------------
From: Justin Richeson
Reply to this message...
Found one big answer on www.dotnet247.com
-
Jul 12th, 2004, 12:10 PM
#3
Thread Starter
Junior Member
Another Good Find
http://www.kquery.com/forums/index.php?showtopic=953
The . net Vb uses System.sockets
but ill paste you a little code you can use
CODE
Imports System.Net
Imports System.Net.Sockets
The next i the socket timeout etc.
CODE
Public Property Timeout() As Integer
Get
Return UDPSocket.Timeout
End Get
Set(ByVal Value As Integer)
UDPSocket.Timeout = Value
End Set
End Property
And now the UDP Class
CODE
#Region "UDP Socket class"
Public Class UDPClass
Private _Timeout As Integer = 1000
Private _ServerResponse As String
Private _ServerResponseReceived As Boolean = False
Private _ReceiveBuffer(4096) As Byte
#Region "Properties"
Public Property Timeout() As Integer
Get
Return _Timeout
End Get
Set(ByVal Value As Integer)
_Timeout = Value
End Set
End Property
Public ReadOnly Property ServerResponse() As String
Get
Return _ServerResponse
End Get
End Property
#End Region
#Region "Socket stuff"
Private UDPSocket As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Private Host As IPEndPoint
Private Listen As New IPEndPoint(IPAddress.Any, 0)
#End Region
#Region "Connection"
Public Function Connect(ByVal IP As String, ByVal Port As Integer) As Boolean
Try
' Connect to IP, Port on UDP protocol
Host = New IPEndPoint(IPAddress.Parse(IP), Port)
UDPSocket.Connect(Host)
' Start the packet listener
ReceivePacket()
Return True
Catch
Return False
End Try
End Function
#End Region
#Region "Send Commands / Receive"
Public Sub Send(ByVal Command() As Byte)
' Send the command to the server and set the
' received response to false
_ServerResponseReceived = False
UDPSocket.Send(Command)
End Sub
Public Function WaitForResponse() As String
' Wait for response from the ReceivePacket sub
' if timeout or error then output a empty string
' else send the received string
If WaitForResponseToBeSent() = False Then
Return ""
Else
Return _ServerResponse
End If
End Function
Private Sub ReceivePacket()
' Start the callback process for receiving data
UDPSocket.BeginReceiveFrom(_ReceiveBuffer, 0, _ReceiveBuffer.Length, SocketFlags.None, Listen, AddressOf ReceivePacket, Nothing)
End Sub
Private Sub ReceivePacket(ByVal ar As IAsyncResult)
' Will only receive a single packet ok for testing
Try
' Check if there any data
Dim Bytes As Integer = UDPSocket.EndReceiveFrom(ar, Listen)
' Data is there now start to place in text buffer
If Bytes > 0 Then
' Indicate the server has sent a response
_ServerResponseReceived = True
_ServerResponse = ASCII.GetString(_ReceiveBuffer, 0, Bytes)
' Start the listen again
UDPSocket.BeginReceiveFrom(_ReceiveBuffer, 0, _ReceiveBuffer.Length, SocketFlags.None, Listen, AddressOf ReceivePacket, Nothing)
Else
' Socket closed then display EOP at console
Console.WriteLine("EOP")
End If
Catch ex As Exception
Console.WriteLine(ex.ToString)
End Try
End Sub
#End Region
#Region "Response Waiting"
Private Function WaitForResponseToBeSent() As Boolean
' This function monitors _ServerResponseReceived if a server
' has sent info then its set to true. If a timeout occurs then
' return false other wise return true
Dim StartTime As Long = Environment.TickCount
While (_ServerResponseReceived = False) And ((Environment.TickCount - StartTime) < _Timeout)
Application.DoEvents()
End While
If (_ServerResponseReceived = False) Then Return False Else Return True
End Function
#End Region
End Class
-
Jul 13th, 2004, 09:03 AM
#4
Thread Starter
Junior Member
Code Above
Below is my code and I still am not receiving anything off the socket, it just continues running and never picks up. Some one p-lease help me!!!!!!!!!!!!!!!!!!!1
''''''''''''''''''''''SERVER'''''''''''''''''''''''''''''
Option Explicit On
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Text
Imports System.Threading
Imports System.IO
#Region "UDP Socket class"
Public Class UdpAsyncServer
Private _Timeout As Integer = 1000
Private _ServerResponse As String
Private _ServerResponseReceived As Boolean = False
Private _ReceiveBuffer(4096) As Byte
Public Event updDataRecieved(ByVal data As String)
#Region "Properties"
Public Property Timeout() As Integer
Get
Return _Timeout
End Get
Set(ByVal Value As Integer)
_Timeout = Value
End Set
End Property
Public ReadOnly Property ServerResponse() As String
Get
Return _ServerResponse
End Get
End Property
#End Region
#Region "Socket stuff"
Private UDPSocket As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Private Host As IPEndPoint
Private Listen As New IPEndPoint(Dns.GetHostByName("nmccreapc").AddressList(0), 11)
#End Region
#Region "Connection"
Public Function Connect(ByVal IP As String, ByVal Port As Integer) As Boolean
Try
' Connect to IP, Port on UDP protocol
Host = New IPEndPoint(Dns.GetHostByName(IP).AddressList(0), Port)
UDPSocket.Bind(Host)
' Start the packet listener
ReceivePacket()
Return True
Catch
Return False
End Try
End Function
#End Region
#Region "Send Commands / Receive"
Public Sub Send(ByVal Command() As Byte)
' Send the command to the server and set the
' received response to false
_ServerResponseReceived = False
UDPSocket.Send(Command)
End Sub
Public Function WaitForResponse() As String
' Wait for response from the ReceivePacket sub
' if timeout or error then output a empty string
' else send the received string
If WaitForResponseToBeSent() = False Then
Return ""
Else
Return _ServerResponse
End If
End Function
Private Sub ReceivePacket()
' Start the callback process for receiving data
UDPSocket.BeginReceive(_ReceiveBuffer, 0, _ReceiveBuffer.Length, SocketFlags.None, New AsyncCallback(AddressOf OnReceivePacket), Nothing)
End Sub
Private Sub OnReceivePacket(ByVal ar As IAsyncResult)
' Will only receive a single packet ok for testing
Try
' Check if there any data
Dim Bytes As Integer = UDPSocket.EndReceive(ar)
' Data is there now start to place in text buffer
If Bytes > 0 Then
' Indicate the server has sent a response
_ServerResponseReceived = True
_ServerResponse = Encoding.ASCII.GetString(_ReceiveBuffer, 0, Bytes)
' Start the listen again
UDPSocket.BeginReceive(_ReceiveBuffer, 0, _ReceiveBuffer.Length, SocketFlags.None, New AsyncCallback(AddressOf OnReceivePacket), Nothing)
RaiseEvent updDataRecieved(_ServerResponse)
Else
UDPSocket.BeginReceive(_ReceiveBuffer, 0, _ReceiveBuffer.Length, SocketFlags.None, New AsyncCallback(AddressOf OnReceivePacket), Nothing)
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
#End Region
#Region "Response Waiting"
Private Function WaitForResponseToBeSent() As Boolean
' This function monitors _ServerResponseReceived if a server
' has sent info then its set to true. If a timeout occurs then
' return false other wise return true
Dim StartTime As Long = Environment.TickCount
While (_ServerResponseReceived = False) And ((Environment.TickCount - StartTime) < _Timeout)
Application.DoEvents()
End While
If (_ServerResponseReceived = False) Then Return False Else Return True
End Function
#End Region
End Class
#End Region
''''''''''''''''''''Client'''''''''''''''''''''''''''
Imports System
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Imports System.Text
Imports System.IO
#Region "UDP Client Socket class"
Public Class UdpAsyncClient
Private _Timeout As Integer = 1000
Private _ClientResponse As String
Private _ClientResponseReceived As Boolean = False
Private _ReceiveBuffer(4096) As Byte
#Region "Properties"
Public Property Timeout() As Integer
Get
Return _Timeout
End Get
Set(ByVal Value As Integer)
_Timeout = Value
End Set
End Property
Public ReadOnly Property ClientResponse() As String
Get
Return _ClientResponse
End Get
End Property
#End Region
#Region "Socket stuff"
Private UDPSocket As New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Private Host As New IPEndPoint(Dns.GetHostByName("nmccreapc").AddressList(0), 0)
Private Client As IPEndPoint
#End Region
#Region "Connection"
Public Function Connect(ByVal IP As String, ByVal Port As Integer, ByVal data As String) As Boolean
Try
' Connect to IP, Port on UDP protocol
Client = New IPEndPoint(Dns.GetHostByName(IP).AddressList(0), Port)
UDPSocket.Bind(Host)
' Start the packet listener
SendPacket(data)
Return True
Catch
Return False
End Try
End Function
#End Region
#Region "Send Commands / Receive"
Public Sub Send(ByVal Command() As Byte)
' Send the command to the server and set the
' received response to false
_ClientResponseReceived = False
UDPSocket.Send(Command)
End Sub
Public Function WaitForResponse() As String
' Wait for response from the ReceivePacket sub
' if timeout or error then output a empty string
' else send the received string
If WaitForResponseToBeSent() = False Then
Return ""
Else
Return _ClientResponse
End If
End Function
Private Sub SendPacket(ByVal data As String)
' Start the callback process for Sending data
_ReceiveBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(data)
UDPSocket.BeginSendTo(_ReceiveBuffer, 0, _ReceiveBuffer.Length, SocketFlags.None, Host, New AsyncCallback(AddressOf OnSendPacket), Nothing)
End Sub
Private Sub OnSendPacket(ByVal ar As IAsyncResult)
' Will only receive a single packet ok for testing
Try
' Check if there any data
Dim Bytes As Integer = UDPSocket.EndSendTo(ar)
' Data is there now start to place in text buffer
If Bytes > 0 Then
' Indicate the Client has sent a response
_ClientResponseReceived = True
_ClientResponse = Encoding.ASCII.GetString(_ReceiveBuffer, 0, Bytes)
Else
' Socket closed then display EOP at console
MsgBox("EOP")
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
#End Region
#Region "Response Waiting"
Private Function WaitForResponseToBeSent() As Boolean
' This function monitors _ServerResponseReceived if a server
' has sent info then its set to true. If a timeout occurs then
' return false other wise return true
Dim StartTime As Long = Environment.TickCount
While (_ClientResponseReceived = False) And ((Environment.TickCount - StartTime) < _Timeout)
Application.DoEvents()
End While
If (_ClientResponseReceived = False) Then Return False Else Return True
End Function
#End Region
End Class
#End Region
-
Jul 17th, 2004, 12:22 PM
#5
Thread Starter
Junior Member
Microsoft Async Bugs
Ok, from talking with another company I have found out that the Asynchronous calls are buggy for Microsoft. So I have resorted to callingthreads and receiving the data synchronously inside them.
Ill post the code later.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|