UDP 通讯中 接收byte的时候停止了!!

xiaoyao1212121 2012-09-20 01:03:34
void ReceiveMessage()
{
//UdpClientB = new UdpClient(portclient); //B开启的端口号
//remotePoint = new IPEndPoint(IPAddress.Any, 0);
int recv;
byte[] bytes = new byte[1024];

IPEndPoint ipt = new IPEndPoint(IPAddress.Any, 13000);
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
server.Bind(ipt);

while (true)
{
try
{
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
EndPoint Remote = (EndPoint)(sender);
recv = server.ReceiveFrom(bytes, ref Remote);

MessagePP com = (MessagePP)DeserializeObject(bytes);
if (com.command == 0)
{
ReceivedACK = true;
}
else
{
//收的都是图片了
MessageBox.Show("B已经收到了A发来的图片消息了");
}

}
catch
{

}
}
}


单步调试,到了红色的那行代码处,没有继续往下运行了.....求助...正在弄UDP打洞,这个为Client,监听着自己这边的一个端口,然后要得到其他Client发过来的数据
...全文
200 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaoyao1212121 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
那你就继续再看,第10章第3节第3、4、5小节,你就明白在一般情况下,必然是互相知道对方客户端的本地地址(客户端提交)和公网地址(服务器提供给),然后先本地,本地不行,再公网来打洞。你上面的代码我没仔细看,好像有第一次第二次第几次的,其实没那么繁琐,互相发一次就行,此时只有一个客户端能收到,之后继续发就没问题了。
看网上的代码真的没有看书快,那些代码往往会灌输很多错误的或者多余的东西,沉下心看书……
[/Quote]


同一个NAT下已经打通了....
现在不同的NAT还没开始打!!因为那个PORT的问题,求速速指点哈》。。
xiaoyao1212121 2012-09-21
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
那你就继续再看,第10章第3节第3、4、5小节,你就明白在一般情况下,必然是互相知道对方客户端的本地地址(客户端提交)和公网地址(服务器提供给),然后先本地,本地不行,再公网来打洞。你上面的代码我没仔细看,好像有第一次第二次第几次的,其实没那么繁琐,互相发一次就行,此时只有一个客户端能收到,之后继续发就没问题了。
看网上的代码真的没有看书快,那些代码往往会灌输很多错误的或者多余的东西,沉下心看书……
[/Quote]

嘿嘿..又要打搅你了...
那个先 用内网IP打洞,再用外网IP打洞,
1.比如A的内网IP是192.168.1.55,记录下来传到B,那个传过去的port是自己设定的么?
2.到外网打洞的时候,A的外网IP:PORT(通过Server得到的),然后UdpClient,不是要监听它的一个端口么,那是不是要从Server那里在拿自己的外网Port回来绑定???
xiaoyao1212121 2012-09-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
你的AB在同一局域网内吗?对于两个客户端处于同一局域网内的情况,因为有的路由器不支持局域网内部访问其公网地址的回环,需要用本地地址访问本地客户端。所以打洞的时候,往往要发送本地地址到中转服务器,服务器将客户端的本地地址和外网地址都发送给另一个客户端,两个客户端分别通过对方的公网地址和本地地址打洞,来解决两个客户端处于同一局域网内的问题。
[/Quote]

哇...我是在我自己的计算机上测试的...服务器 和 A 还有B 都是我自己的电脑上测试
这样不行么???我现在察觉是不是这样:
A -> Server: 这时候 Server记录下A的IP和port(把A和Server连上的这个ip+port发给B,而我上面UDP是自己指定A的port,然后A去"监听")

然后听你这么一说 我又迷糊了...呵呵,这个东东 我做了两天了...都不知道是哪里出问题....
哈哈,你如果有空的话 麻烦花你一些时间 给我回复下哈...

如果按你说的那样,那我在同一个局域网是这样做,那如果不同局域网,代码就要改了??还是用一样的代码也可以??
lizhibin11 2012-09-20
  • 打赏
  • 举报
回复
你的AB在同一局域网内吗?对于两个客户端处于同一局域网内的情况,因为有的路由器不支持局域网内部访问其公网地址的回环,需要用本地地址访问本地客户端。所以打洞的时候,往往要发送本地地址到中转服务器,服务器将客户端的本地地址和外网地址都发送给另一个客户端,两个客户端分别通过对方的公网地址和本地地址打洞,来解决两个客户端处于同一局域网内的问题。
xiaoyao1212121 2012-09-20
  • 打赏
  • 举报
回复
A, B的ip都用中间的server(服务器)来做中转,得到对方的ip都放在holeIp里面,这里没问题


#region 打洞A->B的函数
public UdpClient UdpClientA;
/// <summary>
/// 用来发送图片过去给B和打洞
/// </summary>
void RunHole()
{
//holeip --- 为得到的B的公网ip, 端口默认用13000
//先往B打洞...,打洞的时候要设置一个最大的打洞次数...如果打通了就不再打了...至于

打通没打通,就看接收线程有没有接收到命令为0的包

UdpClient UdpSendA = new UdpClient();
IPEndPoint sendIp = new IPEndPoint(IPAddress.Parse(holeip), 13000);

while (true)
{
//sendA.Connect(remote);
if (ReceivedACK == false)
{
int i;
int j;
int flag = 0;
MessagePP sendBag = new MessagePP();
sendBag.command = 0;
Byte[] buffer = SerializeObject(sendBag);
for (i = 0; i < MaxHole; ++i)
{
UdpSendA.Send(buffer, buffer.Length, sendIp);
for (j = 0; j < 10; ++j)
{
if (ReceivedACK == true)
{
flag = 1; //标志flag = 1;然后跳出来之后,再判断如果flag =

1的话再跳出一个循环
break;
}
else
{
Thread.Sleep(300); //线程稍微睡一下,等一下那边接收线程看

对方打洞过来了没
}
}
if (flag == 1)
{
break;
}
}
}
else
{
//发送视频图片了
MessageBox.Show("B已经接到了A的其他内容的信息了");
}
}
}
/// <summary>
/// 用来接收B发来图片和接收那个打洞消息
/// </summary>
void SuccedHole()
{
//来监听自己开放的端口porthost,看B发了什么东西过来,如果是打洞消息的话标志一下

B向我打了洞

UdpClientB = new UdpClient(24000);
IPEndPoint senderRemote = null;

while (true)
{
if (UdpClientB.Available != 0)
{
try
{
Byte[] buffer = UdpClientB.Receive(ref senderRemote);
MessagePP com = (MessagePP)DeserializeObject(buffer);
if (com.command == 0)
{
ReceivedACK = true;
}
else
{
//收的都是图片了
MessageBox.Show("B已经收到了A发来的图片消息了");
}

}
catch (Exception ex)
{
string st = ex.Message;
}
}
}
}
#endregion

#region 打洞B->A的函数

public UdpClient UdpClientB;
public IPEndPoint remotePoint;
public IPEndPoint otherPoint;
/// <summary>
/// 用来发送图片过去给A和打洞
/// </summary>
void SendMessage()
{
//ip已经传进来了,存放在holeip,然后端口默认用24000,ReceivedACK一开始等于false,

直到接收到对方发来的东东,之后变成true

UdpClient UdpSendB = new UdpClient();
IPEndPoint sendIp = new IPEndPoint(IPAddress.Parse(holeip), 24000);
while (true)
{
if (ReceivedACK == false)
{
int i;
int j;
int flag = 0;
MessagePP sendBag = new MessagePP();
sendBag.command = 0;
Byte[] buffer = SerializeObject(sendBag);
for (i = 0; i < MaxHole; ++i)
{
UdpSendB.Send(buffer,buffer.Length,sendIp);
for (j = 0; j < 10; ++j)
{
if (ReceivedACK == true)
{
flag = 1; //标志flag = 1;然后跳出来之后,再判断如果flag =

1的话再跳出一个循环
break;
}
else
{
Thread.Sleep(300); //线程稍微睡一下,等一下那边接收线程看

对方打洞过来了没
}
}
if (flag == 1)
{
break;
}
}
}
else
{
//发送视频图片了
MessageBox.Show("B已经接到了A的其他内容的信息了");
}
}
}
/// <summary>
/// 用来接收A发来图片和接收那个打洞消息
/// </summary>
void ReceiveMessage()
{
IPEndPoint senderRemote = null;
UdpClientA = new UdpClient(13000); //B监听13000端口
while (true)
{
//Socket clientb = s.Accept();
if(UdpClientA.Available != 0)
{
try
{
Byte[] buffer = UdpClientA.Receive(ref senderRemote);

MessagePP com = (MessagePP)DeserializeObject(buffer);
if (com.command == 0)
{
ReceivedACK = true;
}
else
{
//收的都是图片了
MessageBox.Show("B已经收到了A发来的图片消息了");
}

}
catch (Exception ex)
{
string st = ex.Message;
}
}
}
}
#endregion
xiaoyao1212121 2012-09-20
  • 打赏
  • 举报
回复
我发现了......打洞发出来的send。。。
好像另一个Client不能收到消息,所以停在那里了
哈哈,贴一下这两端代码哈...大家来看看呗!!
xiaoyao1212121 2012-09-20
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]
那你就继续再看,第10章第3节第3、4、5小节,你就明白在一般情况下,必然是互相知道对方客户端的本地地址(客户端提交)和公网地址(服务器提供给),然后先本地,本地不行,再公网来打洞。你上面的代码我没仔细看,好像有第一次第二次第几次的,其实没那么繁琐,互相发一次就行,此时只有一个客户端能收到,之后继续发就没问题了。
看网上的代码真的没有看书快,那些代码往往会灌输很多错误的或者多余的东西,沉下心看书……
[/Quote]

恩...受教...!我马上去看!
lizhibin11 2012-09-20
  • 打赏
  • 举报
回复
那你就继续再看,第10章第3节第3、4、5小节,你就明白在一般情况下,必然是互相知道对方客户端的本地地址(客户端提交)和公网地址(服务器提供给),然后先本地,本地不行,再公网来打洞。你上面的代码我没仔细看,好像有第一次第二次第几次的,其实没那么繁琐,互相发一次就行,此时只有一个客户端能收到,之后继续发就没问题了。
看网上的代码真的没有看书快,那些代码往往会灌输很多错误的或者多余的东西,沉下心看书再实验。
xiaoyao1212121 2012-09-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
所有的打洞都是会对对方的本地地址和公网地址分别打洞的,因为作为通用软件预先无法判断两个客户端是否在同一局域网内。
其实你到处找代码的时间内,不如花二十分钟看一下《Windows网络与通信程序设计》的相关部分,再花一小时看一下《Tcp/Ip协议详解》中关于可靠性的相关章节,你用UDP传输文件时会参考到Tcp保证可靠性的做法。
[/Quote]

Windows网络与通信程序设计 已经看了..
不知道是因为我理解能力不够好还是怎么的...我觉得他的意思就是 在server处把A的公网ip + port发给B,然后B往A打洞,之后通知Server,再让server通知A去往B打洞...可这样写起来就报错了....嘿嘿,以为别人前人写过的代码 直接copy,会快点!!!现在很急~~~
《Tcp/Ip协议详解》中关于可靠性的相关章节,等我先打洞打通了..再考虑传输完整性的问题哈!!
【ps: 我还是觉得我贴出来的那段代码好像可以】
你A把说外网和内网都发给B之后,那B要怎么去连它???
嘿嘿....如果可以最好贴一下 伪代码 或者源代码哈......
比较笨哈,这样理解不了哈~~
lizhibin11 2012-09-20
  • 打赏
  • 举报
回复
所有的打洞都是会对对方的本地地址和公网地址分别打洞的,因为作为通用软件预先无法判断两个客户端是否在同一局域网内。
其实你到处找代码的时间内,不如花二十分钟看一下《Windows网络与通信程序设计》的相关部分,再花一小时看一下《Tcp/Ip协议详解》中关于可靠性的相关章节,你用UDP传输文件时会参考到Tcp保证可靠性的做法。

110,896

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧