从TCP更改为UDP [英] Changing from TCP to UDP

查看:122
本文介绍了从TCP更改为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆