从TCP更改为UDP [英] Changing from TCP to UDP
问题描述
嗨。
前一段时间我在局域网网络上进行了一次小型VoIP聊天,我使用的是TCP协议。
但由于TCP上的开销(导致声音中的主要环回) 我正在尝试更改为UDP,但遇到了一些问题。
我使用BeginAccept将新客户端添加到列表中,但除非我使用"Listen",否则我不能使用BeginAccept首先。
但UDP不具备"监听"功能,所以我有点卡住了。
(这是关于服务器应用程序)
以下是我用于TCP版本的大部分代码
Imports System.Collections.Generic
Imports System.Text
Imports System.Threading
Imports System.Net
Imports System.Net.Sockets
Imports System.Collections
Imports System.Windows.Forms
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging
Namespace SocketCoder
Class SocketCoderBinaryServer
Public Shared ClientsList As New ArrayList()
Shared Listener_Socket As Socket
Public Shared Newclient As SocketCoderClient
Public Shared value As String = Nothing
Public Shared ny As New UdpClient()
'(1)建立服务器
公共共享功能Start_Video_Server(端口为整数)字符串
尝试
Dim AddressAr As IPAddress()= Nothing
Dim ServerHostName As [String] =""
尝试
ServerHostName = Dns.GetHostName()
Dim ipEntry As IPHostEntry = Dns.GetHostByName(ServerHostName)
AddressAr = ipEntry.AddressList
Catch ex1 As Exception
返回ex1.Message
结束尝试
Listener_Socket =新套接字(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp)
Dim ipEndPoint As New IPEndPoint(IPAddress.Any,5000)
Listener_Socket.Bind(ipEndPoint)
Listener_Socket.Listen(100)
((IPEndPoint)rsock.RemoteEndPoint ).Address.ToString();
Listener_Socket.BeginAccept(New AsyncCallback(AddressOf EndAccept),Listener_Socket)
Return("Listening On Port"& Port&" ... OK")
Catch ex As Exception
返回ex.Message
结束尝试
结束函数
'(2)接受客户端Conncetion
私有共享子EndAccept(ar作为IAsyncResult)
尝试
Listener_Socket = DirectCast(ar.AsyncState,Socket)
AddClient(Listener_Socket.EndAccept(ar))
Listener_Socket.BeginAccept(New AsyncCallback(AddressOf EndAccept),Listener_Socket)
Catch generatedExceptionName As Exception
End Try
End Sub
'(3)创建一个Socket for每个客户端并将其Socket添加到ArrayList
私有共享子AddClient(sockClient作为套接字)
Newclient = New SocketCoderClient(sockClient)
value =" User:" &安培; DirectCast(Newclient.ReadOnlySocket.RemoteEndPoint,IPEndPoint).Address.ToString()& "已连接"
ClientsList.Add(Newclient)
'client.Sock.RemoteEndPoint - "已加入房间"
Newclient.SetupRecieveCallback()
'return" User:" + value.ToString()+"已连接";
结束子
'(4)将收到的数据发送给房间内的所有客户
私有共享子OnRecievedData(ar作为IAsyncResult)
Dim client As SocketCoderClient = DirectCast(ar.AsyncState,SocketCoderClient)
Dim aryRet As Byte()= client.GetRecievedData(ar)
如果aryRet.Length< 1然后
'client.Sock.RemoteEndPoint - "已离开房间"
client.ReadOnlySocket.Close()
返回
结束如果
client.SetupRecieveCallback()
End Sub
公共共享函数ShutDown()As String
尝试
Listener_Socket.Close()
GC.Collect()
GC.WaitForPendingFinalizers()
返回(" ;关闭...确定")
Catch ex As Exception
返回(ex.Message)
结束尝试
结束函数
朋友类SocketCoderClient
'为每个客户创建一个新套接字
私有New_Socket As Socket
私有缓冲区As Byte()= Nothing
Public Sub New(PassedSock As Socket)
New_Socket = PassedSock
End Sub
Public ReadOnly Property ReadOnlySocket()As Socket
Get
返回New_Socket
结束获取
结束物业
Public Sub SetupRecieveCallback()
尝试
buffer = New Byte(3999){}
Dim rec ieveData As New AsyncCallback(AddressOf SocketCoderBinaryServer.OnRecievedData)
New_Socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,recieveData,Me)
Catch generatedExceptionName As Exception
End Try
End Sub
公共函数GetRecievedData(ar As IAsyncResult)As Byte()
Dim nBytesRec As Integer = 0
尝试
nBytesRec = New_Socket.EndReceive(ar)
捕获
结束尝试
Dim byReturn As Byte()=新字节(nBytesRec - 1){}
Array.Copy(buffer,byReturn,nBytesRec)
返回byReturn
结束功能
结束等级
结束等级
结束命名空间
$
这里是UDP版本的等价物(现在)
Imports System.Collections.Generic
Imports System.Text
Imports System.Threading
Imports System.Net
Imports System.Net.Sockets
Imports System .Collections
Imports System.Windows.Forms
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging
Namespace SocketCoder
Class SocketCoderBinaryServer
Public Shared ClientsList As New ArrayList()
Shared Listener_Socket As Socket
Public Shared Newclient As SocketCoderClient
Public Shared value As String = Nothing
Public Shared ny As New UdpClient ()
'(1)建立服务器
公共共享函数Start_Video_Server(ByVal Port As Integer)As String
尝试
Dim byteData()As Byte = New字节(1024){}
Dim AddressAr As IPAddress()= Nothing
Dim ServerHostName As [String] =""
尝试
ServerHostName = Dns.GetHostName()
Dim ipEntry As IPHostEntry = Dns.GetHostByName(ServerHostName)
AddressAr = ipEntry.AddressList
Catch ex1 As Exception
返回ex1.Message
结束尝试
Listener_Socket =新套接字(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp)
Dim ipEndPoint As New IPEndPoint(IPAddress.Any,5000)
Listener_Socket.Bind(ipEndPoint)
'Listener_Socket.Listen(100)
'value =((IPEndPoint)rsock.RemoteEndPoint).Address.ToString();
Listener_Socket.BeginReceiveFrom(byteData,0,byteData.Length,SocketFlags.None,ipEndPoint,New AsyncCallback(AddressOf AddClient),ipEndPoint)
Return("Listening On Port"& Port&" ; ... OK")
Catch ex As Exception
返回ex.Message
结束尝试
结束函数
'(2)接受客户一致意见
Private Shared Sub EndAccept(ByVal ar As IAsyncResult)
尝试
Listener_Socket = DirectCast(ar.AsyncState,Socket)
AddClient(Listener_Socket.EndAccept(ar))
Listener_Socket.BeginAccept(New AsyncCallback(AddressOf EndAccept),Listener_Socket)
Catch generatedExceptionName As Exception
End Try
End Sub
'(3)为每个客户端创建一个套接字,并将他的套接字添加到ArrayList
私有共享子AddClient(ByVal sockClient作为套接字)
Newclient = New SocketCoderClient(sockClient)
value ="用户:& QUOT; &安培; DirectCast(Newclient.ReadOnlySocket.RemoteEndPoint,IPEndPoint).Address.ToString()& "已连接"
ClientsList.Add(Newclient)
'client.Sock.RemoteEndPoint - "已加入房间"
Newclient.SetupRecieveCallback()
'return" User:" + value.ToString()+"已连接";
结束子
'(4)将收到的数据发送给房间内的所有客户
私有共享子OnRecievedData(ByVal ar As IAsyncResult)
Dim client As SocketCoderClient = DirectCast(ar.AsyncState,SocketCoderClient)
Dim aryRet As Byte()= client.GetRecievedData(ar)
如果aryRet.Length< 1然后
'client.Sock.RemoteEndPoint - "已离开房间"
client.ReadOnlySocket.Close()
返回
结束如果
client.SetupRecieveCallback()
End Sub
公共共享函数ShutDown()As String
尝试
Listener_Socket.Close()
GC.Collect()
GC.WaitForPendingFinalizers()
返回(" ;关闭...确定")
Catch ex As Exception
返回(ex.Message)
结束尝试
结束函数
朋友类SocketCoderClient
'为每个客户创建一个新套接字
私有New_Socket As Socket
私有缓冲区As Byte()= Nothing
Public Sub New(ByVal PassedSock As Socket)
New_Socket = PassedSock
End Sub
Public ReadOnly Property ReadOnlySocket()As Socket
Get
Return New_Socket
End Get
End Property
Public Sub SetupRecieveCallback()
尝试
buffer = New Byte(3999){}
Dim re cieveData As New AsyncCallback(AddressOf SocketCoderBinaryServer.OnRecievedData)
New_Socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,recieveData,Me)
Catch generatedExceptionName As Exception
End Try
End Sub
公共函数GetRecievedData(ByVal ar As IAsyncResult)As Byte()
Dim nBytesRec As Integer = 0
尝试
nBytesRec = New_Socket.EndReceive(ar)
Catch
结束尝试
Dim byReturn As Byte()= New Byte(nBytesRec - 1){}
Array.Copy(buffer,byReturn,nBytesRec)
Return byReturn
结束功能
结束等级
结束等级
结束命名空间
希望有人可以帮我搞定。
提前致谢:)
$
使用UDP,你只需要绑定到端口,然后使用ReceiveFrom和SendFrom方法或等效的异步方法。
" If如果您使用的是无连接协议,例如UDP,则可以使用 BeginSendTo 和
EndSendTo 发送数据报,
BeginReceiveFrom 和
EndReceiveFrom 以接收数据报。"来自
http://msdn.microsoft.com/en -us /库/ system.net.sockets.socket.aspx 。我可以稍后发布一些示例c#代码,但你的调用应该是:
创建套接字
绑定(端点)
ReceiveFrom(一些新的端点)。 //非异步版本
- 流程数据
SentTo(客户端点)//非异步版本
您不需要Listen,也不能使用仅适用于TCP的接收。
以下是一些示例c#代码:
//创建udp套接字,将其绑定在端口号上(告诉它允许来自任何ip的连接)。
ServerSocket = new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
EndPoint ep =新IPEndPoint(IPAddress.Any,PortNumber);
ServerSocket.Bind(ep);
Hope这有助于,
Brad
$
Hi.
A while ago i did a small VoIP chat for LAN-network where i used TCP protocol.
But due to the overhead on TCP (causes major loopback in the sound) i'm trying to change to UDP, but got some problem.
I used BeginAccept to add new clients to a list, but i can't use BeginAccept unless i use "Listen" first.
But UDP dose not have the "Listen"-function, so i'm kind of stuck.
(This is on the server-application)
Here is most the code i use for the TCP version
Imports System.Collections.Generic
Imports System.Text
Imports System.Threading
Imports System.Net
Imports System.Net.Sockets
Imports System.Collections
Imports System.Windows.Forms
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging
Namespace SocketCoder
Class SocketCoderBinaryServer
Public Shared ClientsList As New ArrayList()
Shared Listener_Socket As Socket
Public Shared Newclient As SocketCoderClient
Public Shared value As String = Nothing
Public Shared ny As New UdpClient()
' (1) Establish The Server
Public Shared Function Start_Video_Server(Port As Integer) As String
Try
Dim AddressAr As IPAddress() = Nothing
Dim ServerHostName As [String] = ""
Try
ServerHostName = Dns.GetHostName()
Dim ipEntry As IPHostEntry = Dns.GetHostByName(ServerHostName)
AddressAr = ipEntry.AddressList
Catch ex1 As Exception
Return ex1.Message
End Try
Listener_Socket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Dim ipEndPoint As New IPEndPoint(IPAddress.Any, 5000)
Listener_Socket.Bind(ipEndPoint)
Listener_Socket.Listen(100)
((IPEndPoint)rsock.RemoteEndPoint).Address.ToString();
Listener_Socket.BeginAccept(New AsyncCallback(AddressOf EndAccept), Listener_Socket)
Return ("Listening On Port " & Port & "... OK")
Catch ex As Exception
Return ex.Message
End Try
End Function
' (2) Accept Clients Conncetion
Private Shared Sub EndAccept(ar As IAsyncResult)
Try
Listener_Socket = DirectCast(ar.AsyncState, Socket)
AddClient(Listener_Socket.EndAccept(ar))
Listener_Socket.BeginAccept(New AsyncCallback(AddressOf EndAccept), Listener_Socket)
Catch generatedExceptionName As Exception
End Try
End Sub
' (3) Create a Socket for Each Client and add his Socket to The ArrayList
Private Shared Sub AddClient(sockClient As Socket)
Newclient = New SocketCoderClient(sockClient)
value = "User: " & DirectCast(Newclient.ReadOnlySocket.RemoteEndPoint, IPEndPoint).Address.ToString() & " has connected"
ClientsList.Add(Newclient)
' client.Sock.RemoteEndPoint - " has joined the room"
Newclient.SetupRecieveCallback()
'return "User: " + value.ToString() + " has connected";
End Sub
' (4) Send The Recieved Data to All Clients in The Room
Private Shared Sub OnRecievedData(ar As IAsyncResult)
Dim client As SocketCoderClient = DirectCast(ar.AsyncState, SocketCoderClient)
Dim aryRet As Byte() = client.GetRecievedData(ar)
If aryRet.Length < 1 Then
'client.Sock.RemoteEndPoint - "has left the room"
client.ReadOnlySocket.Close()
Return
End If
client.SetupRecieveCallback()
End Sub
Public Shared Function ShutDown() As String
Try
Listener_Socket.Close()
GC.Collect()
GC.WaitForPendingFinalizers()
Return ("Shutdown ... OK")
Catch ex As Exception
Return (ex.Message)
End Try
End Function
Friend Class SocketCoderClient
' To create a new socket for each client
Private New_Socket As Socket
Private buffer As Byte() = Nothing
Public Sub New(PassedSock As Socket)
New_Socket = PassedSock
End Sub
Public ReadOnly Property ReadOnlySocket() As Socket
Get
Return New_Socket
End Get
End Property
Public Sub SetupRecieveCallback()
Try
buffer = New Byte(3999) {}
Dim recieveData As New AsyncCallback(AddressOf SocketCoderBinaryServer.OnRecievedData)
New_Socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, recieveData, Me)
Catch generatedExceptionName As Exception
End Try
End Sub
Public Function GetRecievedData(ar As IAsyncResult) As Byte()
Dim nBytesRec As Integer = 0
Try
nBytesRec = New_Socket.EndReceive(ar)
Catch
End Try
Dim byReturn As Byte() = New Byte(nBytesRec - 1) {}
Array.Copy(buffer, byReturn, nBytesRec)
Return byReturn
End Function
End Class
End Class
End Namespace
And here is the equivalent for the UDP version (as for now)
Imports System.Collections.Generic
Imports System.Text
Imports System.Threading
Imports System.Net
Imports System.Net.Sockets
Imports System.Collections
Imports System.Windows.Forms
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Imaging
Namespace SocketCoder
Class SocketCoderBinaryServer
Public Shared ClientsList As New ArrayList()
Shared Listener_Socket As Socket
Public Shared Newclient As SocketCoderClient
Public Shared value As String = Nothing
Public Shared ny As New UdpClient()
' (1) Establish The Server
Public Shared Function Start_Video_Server(ByVal Port As Integer) As String
Try
Dim byteData() As Byte = New Byte(1024) {}
Dim AddressAr As IPAddress() = Nothing
Dim ServerHostName As [String] = ""
Try
ServerHostName = Dns.GetHostName()
Dim ipEntry As IPHostEntry = Dns.GetHostByName(ServerHostName)
AddressAr = ipEntry.AddressList
Catch ex1 As Exception
Return ex1.Message
End Try
Listener_Socket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)
Dim ipEndPoint As New IPEndPoint(IPAddress.Any, 5000)
Listener_Socket.Bind(ipEndPoint)
' Listener_Socket.Listen(100)
'value = ((IPEndPoint)rsock.RemoteEndPoint).Address.ToString();
Listener_Socket.BeginReceiveFrom(byteData, 0, byteData.Length, SocketFlags.None, ipEndPoint, New AsyncCallback(AddressOf AddClient), ipEndPoint)
Return ("Listening On Port " & Port & "... OK")
Catch ex As Exception
Return ex.Message
End Try
End Function
' (2) Accept Clients Conncetion
Private Shared Sub EndAccept(ByVal ar As IAsyncResult)
Try
Listener_Socket = DirectCast(ar.AsyncState, Socket)
AddClient(Listener_Socket.EndAccept(ar))
Listener_Socket.BeginAccept(New AsyncCallback(AddressOf EndAccept), Listener_Socket)
Catch generatedExceptionName As Exception
End Try
End Sub
' (3) Create a Socket for Each Client and add his Socket to The ArrayList
Private Shared Sub AddClient(ByVal sockClient As Socket)
Newclient = New SocketCoderClient(sockClient)
value = "User: " & DirectCast(Newclient.ReadOnlySocket.RemoteEndPoint, IPEndPoint).Address.ToString() & " has connected"
ClientsList.Add(Newclient)
' client.Sock.RemoteEndPoint - " has joined the room"
Newclient.SetupRecieveCallback()
'return "User: " + value.ToString() + " has connected";
End Sub
' (4) Send The Recieved Data to All Clients in The Room
Private Shared Sub OnRecievedData(ByVal ar As IAsyncResult)
Dim client As SocketCoderClient = DirectCast(ar.AsyncState, SocketCoderClient)
Dim aryRet As Byte() = client.GetRecievedData(ar)
If aryRet.Length < 1 Then
'client.Sock.RemoteEndPoint - "has left the room"
client.ReadOnlySocket.Close()
Return
End If
client.SetupRecieveCallback()
End Sub
Public Shared Function ShutDown() As String
Try
Listener_Socket.Close()
GC.Collect()
GC.WaitForPendingFinalizers()
Return ("Shutdown ... OK")
Catch ex As Exception
Return (ex.Message)
End Try
End Function
Friend Class SocketCoderClient
' To create a new socket for each client
Private New_Socket As Socket
Private buffer As Byte() = Nothing
Public Sub New(ByVal PassedSock As Socket)
New_Socket = PassedSock
End Sub
Public ReadOnly Property ReadOnlySocket() As Socket
Get
Return New_Socket
End Get
End Property
Public Sub SetupRecieveCallback()
Try
buffer = New Byte(3999) {}
Dim recieveData As New AsyncCallback(AddressOf SocketCoderBinaryServer.OnRecievedData)
New_Socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, recieveData, Me)
Catch generatedExceptionName As Exception
End Try
End Sub
Public Function GetRecievedData(ByVal ar As IAsyncResult) As Byte()
Dim nBytesRec As Integer = 0
Try
nBytesRec = New_Socket.EndReceive(ar)
Catch
End Try
Dim byReturn As Byte() = New Byte(nBytesRec - 1) {}
Array.Copy(buffer, byReturn, nBytesRec)
Return byReturn
End Function
End Class
End Class
End Namespace
Hope someone can help me get this working.
Thanks in advance :)
With UDP, you just have to Bind to the the port and then use the ReceiveFrom and SendFrom methods or the equivalent async methods.
"If you are using a connectionless protocol such as UDP, you can use BeginSendTo and EndSendTo to send datagrams, and BeginReceiveFrom and EndReceiveFrom to receive datagrams." from the http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.aspx. I can post some sample c# code later, but your calls should be:
Create Socket
Bind(Endpoint)
ReceiveFrom(Some new Endpoint). //non-async version
--process data
SentTo(the client's endpoint) //non-async version
You do not need the Listen and cannot use the Receive as that is for TCP only.
Here's some sample c# code:
//create the udp socket, bind it on the port number (tell it to allow connections from any ip). ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); EndPoint ep = new IPEndPoint(IPAddress.Any, PortNumber); ServerSocket.Bind(ep);
Hope this Helps,
Brad
这篇关于从TCP更改为UDP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!