请考虑以下代码:
client.Send(data, data.Length, endpoint);
byte[] response = client.Receive(ref endpoint);
Run Code Online (Sandbox Code Playgroud)
虽然根据WireShark(网络嗅探器),远程主机确实回复数据,但这里的应用程序只是永远等待数据......由于某种原因,它没有从远程主机接收答案.
有任何想法吗?
我有一台带有多个NIC的计算机 - 而且UDPClient的send方法一直失败.这是代码:
private static void receiveData()
{
recvSock = new UdpClient(PORT);
//recvSock.Client.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, mainInterface);
recvSock.JoinMulticastGroup(IPAddress.Parse(IP), 50);
IPEndPoint iep = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
byte[] data = recvSock.Receive(ref iep);
// Do not include messages from us
if (myIPs.Contains(iep.Address))
continue;
string stringData = Encoding.ASCII.GetString(data, 0, data.Length);
Console.WriteLine("received: " + stringData);
}
}
Run Code Online (Sandbox Code Playgroud)
PORT = 5000,IP = 224.5.6.7,所以应该没问题.主要问题是我无法通过recvSock.Receive()行.我看到数据包通过wireshark进入 - 但代码只是不会处理它们...
思考?提前致谢!
担
编辑:我可以确认多个NIC导致问题---代码可以正常使用单个NIC.取消注释SetSocketOption行应该允许它使用多个NIC,但它仍然失败....想法?
我必须尽可能快速,实时地通过UDP发送一系列视频帧,当我掌握了基础知识时,我遇到了各种各样的困难.我的一些目标:
数据通常通过拨号发送(因此UDP而不是TCP),但也需要支持快速以太网.
偶尔丢帧(因此UDP而不是TCP)是可以的.
需要低延迟.远程接收的帧应该是最近发送的帧(在缓冲区中等待的帧数不超过几帧).
我需要能够检测有效带宽,以便我可以或多或少地压缩帧以保持帧速率.
我已成功实现了大部分内容:
我将帧数据分解为一个或多个大约500字节的数据报,每个数据报都有一个序列号和其他信息.接收器重新组装整个帧并检测是否缺少任何数据报.
如果接收器检测到超过一定百分比的丢帧(例如,过去10帧中的50%),我向发送方发送TCP消息以减慢50%.发送者比每个后续帧慢慢增加5%的速度.
使用System.Net.Sockets.UdpClient发送和接收数据.
我有一个单独的TCP通道用于控制消息回发送者.
我现在面临的主要困难是检测有效带宽并处理延迟,特别是通过拨号(最大~4,000字节/秒).例如,如果我尝试使用TcpClient.Send()发送100,000字节/秒,则它们似乎到达(没有丢弃的数据报),但是在最后一个数据报到达时具有大的延迟.我认为TcpClient.Send()函数是阻塞的,直到缓冲区能够发送,这会混淆我当前的算法.
任何人都可以指出我的任何信息来源如何:
通过UDP检测实际带宽.
一种更好的动态调整带宽以适应可用管道的算法.
以所需带宽平滑地发送数据.
一种检测并将延迟降至最低的方法.
我在上周一直在转动轮子,每次解决一个问题时,另一个问题似乎是头部.
我在C#中遇到了UdpClient问题.我通过互联网在两个客户端之间传输音频.
在我的麦克风上,采样率为16khz,我发送带有音频的UDP数据包,每个数据包6400字节.这些从来没有通过,除了最后的数据包,自从我关闭录音以来通常大约1200-3400的东西.当我将采样率降低到8khz时,我发送3200字节有效载荷的数据包.由于某些原因,这些总是能够通过.
所以基本上3200以上的任何东西都会变得拙劣(没有测试过确切的数字但是......)为什么这个呢?我想也许UdpClient内部缓冲区太小或什么?由于我流音频数据包被频繁发送.
接收:
private void audioReceive(IAsyncResult asyn)
{
try
{
byte[] temp = audioSock.EndReceive(asyn, ref this.serverEP);
this.waveProvider.AddSamples(temp, 0, temp.Length);
this.textbox_display.Text = this.textbox_display.Text + " got bytes: " + temp.Length;
audioSock.BeginReceive(new AsyncCallback(audioReceive), null);
}
catch (Exception ez)
{
MessageBox.Show("audioReceive: " + this.textbox_nick.Text + " " +ez.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
我找不到任何明显的错误.(该函数的asyn对象是null btw,我不需要使用stateobject,但这不应该与此相关)
我知道UDP不可靠,但考虑到每个3200大小的数据包都通过了,没有6400大小的气味给我带来腥味,特别是最大大小是64kb?
有任何想法吗?
我正在编写一个简单的P2P应用程序来测试在更大的项目中使用UDP穿孔的可行性.
我昨天在家尝试了我的测试应用程序并且他们工作了.
但是,我现在正在工作,相同的代码不再起作用.发送方在这里发送到我们路由器的外部IP地址上的相应端口,但接收方没有得到它们中的任何一个.
在呼叫之前UdpClient.Receive(),接收应用程序将一个数据包发送到它将监听的IP:端口.同样,这适用于我的家庭设置,但不是这里.无论Windows防火墙是打开还是关闭,结果都是相同的,所以这不是问题.
可能是路由器以不同的方式处理这种情况吗?
EDIT1:两个应用程序都在同一台机器上运行.
我正在System.Net.Sockets.UdpClient类的帮助下开发一个动作多人游戏.
它适用于两个玩家,因此应该打开服务器并等待传入的连接.另一个玩家输入主机IP并尝试发送"ping",以确保连接是可能的并且有一个打开的服务器.然后主持人用"乒乓球"回应.
一旦游戏运行,两者都必须向对方发送udp消息,因此他们都需要对手的ip地址.
当然服务器也可以输入客户端IP,但这对我来说似乎是不必要的.
当收到"ping"消息时,如何从udp包中获取客户端IP?
这是我的接收代码(等待ping的服务器):
private void ListenForPing()
{
while (!closeEverything)
{
var deserializer = new ASCIIEncoding();
IPEndPoint anyIP = new IPEndPoint(IPAddress.Any, 0);
byte[] recData = udp.Receive(ref anyIP);
string ping = deserializer.GetString(recData);
if (ping == "ping")
{
Console.WriteLine("Ping received.");
InvokePingReceiveEvent();
}
}
}
Run Code Online (Sandbox Code Playgroud) 这可能是一个愚蠢的问题,但由于我在这里相对较新,所以它...如果我有两个单独的字节数组,我需要接收端作为一个大数组,例如:
byte[] Array1 = {1,1,1}
byte[] Array2 = {2,2,2}
Run Code Online (Sandbox Code Playgroud)
我可以避免创建缓冲区并将每个数组复制到其中,然后发送该缓冲区,如下所示:
byte[] Buffer= new byte[Array1.Length + Array2.Length];
Buffer.BlockCopy(Array1, 0, Buffer, 0, Array1.Length);
Buffer.BlockCopy(Array2, 0, Buffer, Array1.Length, Array2.Length);
udpClient.Send(Buffer, Buffer.Length);
Run Code Online (Sandbox Code Playgroud)
因为如果两者都很大,而且数据速率很高,那么复制会占用很多系统资源......所以我可以告诉udpClient我正在启动UDP碎片,然后这样做:
udpClient.ImStartingOneBigDatagram();
udpClient.Send(Array1, Array1.Length);
udpClient.Send(Array2, Array2.Length);
udpClient.ThatsAllFolks();
Run Code Online (Sandbox Code Playgroud)
并确保接收方获得:
byte[] recv = {1,1,1,2,2,2}
Run Code Online (Sandbox Code Playgroud)
我正在使用C#,我不需要使用UdpClient,我只是在说明我的观点.
当试图处理UdpClient时,我发现这是不可能的.对于以下内容:
UdpClient udpClient = new UdpClient();
udpClient.Dispose();
Run Code Online (Sandbox Code Playgroud)
Visual Studio显示错误:
由于其保护级别,'System.Net.Sockets.UdpClient.Dispose(bool)'无法访问
这是否意味着我应该继承UdpClient并揭露Dispose(因为似乎是任何实现IDisposable应该被处理的共识)?有什么理由我们不应该直接使用这个类吗?或者在打电话后没有什么可以处理掉的Close?
虽然using声明确实有效 - 但在听时却不合适.
我正在使用如下的UDPClient
dim c = New UDPClient(port)
client.CLient.ReceiveTimeout = 1
await client.ReceiveAsync()
Run Code Online (Sandbox Code Playgroud)
但是,即使我设置了超时,await也不会终止或抛出.这是正常的行为吗?
我正在使用recvfrom()将UDP数据报放入我的缓冲区并传递非NULL的from_addr结构和len参数,期望它获取源IP.但是对于第一次调用,它们是NULL.后续调用正在填充addr结构和len字段.这是预期的吗?
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
int
main()
{
struct sockaddr_in myaddr, from_addr;
char from_ip[1024] = "", myip[2014] = "";
char rmsg[1024 * 1024] = "";
int sock_fd=-1,nbytes=0;
int len=0;
unsigned short port=0;
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(sock_fd == -1)
{
perror("Socket");
return -1;
}
printf("IP Addr & Port to bound to :");
scanf("%s%u", myip, &port);
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(port);
inet_pton(AF_INET, myip, &myaddr.sin_addr);
printf("Bound to %s:%u\n", myip, htons(port));
nbytes = bind(sock_fd, &myaddr, …Run Code Online (Sandbox Code Playgroud)