Socket udpServer;
IPEndPoint serverIP=new IPEndPoint(IPAddress.Parse(xxx.xx.x.xxx),9199);
udpServer.Bind(serverIP);
EndPoint.Remote=(EndPoint)serverIP
new Thread(()=>
{
while(true)
{
byte[] data=new byte[102400];
try
{
length=udpServer.ReceiveFrom(data, ref Remote);
if(length<=0)
break;
string str1=Encoding.GetEncoding("GBK").GetString(data,0,length);
Invoke(new ThreadStart(delegate()
{
this.textBox1.ApprendText(str1+Environment.NewLine);
this.textBox1.ScollToCaret();
}))
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
}
}).Start();
将收到的str1逐行添加到textbox1时,会出现丢包
18 个解决方案
#1
udp本来就是不可靠通讯。
你知道有个tcp么?
tcp才是可靠的通讯(之一)。
你知道有个tcp么?
tcp才是可靠的通讯(之一)。
#2
“看程序”没有多大意义,因为连基本的教科书上的概念都保证说“udp丢包是非常正常、非常普遍的”。你可以多看两小本通讯方面的入门书即可有所收获。
#3
UDP本来就是允许丢包的,所以一般运用在视频中~就是卡一下,画面模糊一下也没有关系~
不允许丢包的场景 请用TCP
不允许丢包的场景 请用TCP
#4
各位大神们都发言了,,偶也来围观。。。。
#5
我是在本机上进行通信,我当然知道TCP
#6
UDP是在大量传输数据的时候允许丢包,一般用在视频上。
TCP有握手协议,所以不会丢包,很可靠,但是效率稍微有点低。
TCP有握手协议,所以不会丢包,很可靠,但是效率稍微有点低。
#7
单向传输必须用UPD,因为很多工业现场直接物理隔离了双向传输
#8
LZ可以改异步试试,比多线程效率高
这是我写的一个UPDserver接受你可以参考参考,数据量不小
static DataTable dt;
static DataTable Abbdt;
static SqlHelper objhelper;
static SqlConnection conn;
static OtherClass oc;
// Attributes
private ArrayList m_aryClients = new ArrayList(); // List of Client Connections
public const string GaoxinUDPProtocol = @"FDFDV\d.\d{2}.\d{2}L\d{3}DT(2\d\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])\s+\d{2}:\d{2}:\d{2}),(.*)FEFE";
public const string GaoxinUDPData = @"^[0-9]*:[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?:[0-9]*$";
public const char Comma = ',';
public const char Colon = ':';
static Regex reg;
static Regex dataReg;
/// <summary>
/// Application starts here. Create an instance of this class and use it
/// as the main object.
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
objhelper = new SqlHelper();
conn = objhelper.getConn();
conn.Open();
oc = new OtherClass();
reg = new Regex(GaoxinUDPProtocol);
dataReg = new Regex(GaoxinUDPData);
int nPortListen = oc.lPort();
IPAddress ip = IPAddress.Parse(oc.IPAddress());
IPAddress ipAny = IPAddress.Any;
IPEndPoint ipe = new IPEndPoint(ip, nPortListen);
m_sListen = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
m_sListen.Bind(ipe);
//IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
//EndPoint remote = (EndPoint)sender;
EndPoint remote = (EndPoint)ipe;
PostRecv(ipe);
Console.WriteLine("请按回车键结束!");
Console.ReadKey();
conn.Close();
GC.Collect();
GC.WaitForPendingFinalizers();
}
#region UDP
static Socket m_sListen;
private static void ListenThreadMothed()
{
}
private static void PostRecv(EndPoint endPoint)
{
byte[] buffer = new byte[1048576];
m_sListen.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref endPoint, EndRecv, new AsyncState(buffer, 0, buffer.Length, endPoint));
}
private static void PostSend(byte[] buffer, int offset, int size, EndPoint endPoint)
{
m_sListen.BeginSendTo(buffer,
offset,
size,
SocketFlags.None,
endPoint,
EndSend,
new AsyncState(buffer, offset, size, endPoint));
}
private static void EndRecv(IAsyncResult asyncResult)
{
AsyncState state = (AsyncState)asyncResult.AsyncState;
try
{
m_sListen.EndReceiveFrom(asyncResult, ref state.EndPoint);
if (state.Buffer.Length > 20)
{
string recString = System.Text.Encoding.Default.GetString(state.Buffer);
string[] UDPItems;
string[] UDPItem0;
string strSetp = "0", strInp = "0", strOutp = "0", strFeedBack = "0", strTotal_E = "0", strA_Current = "0", strAB_Voltage = "0", strA_Current2 = "0", strAB_Voltage2 = "0", No1M_Run = "0", No2M_Run = "0";
Match mat = reg.Match(recString.Trim(), 0);
//recString.IndexOf(',');
//recString.IndexOf(':');
if (mat.Success)
{
UDPItems = mat.Groups[4].Value.Split(Comma);
string[] udpItemFor;
UDPItem0 = UDPItems[0].Split(Colon);
int intNO = int.Parse(UDPItem0[0]);
foreach (var item in UDPItems)
{
udpItemFor = item.Split(Colon);
int strNO = int.Parse(udpItemFor[0]);
if (strNO - intNO >= 80)
{
break;
}
int theV = strNO % 80;
switch (theV)
{
case 0: strSetp = udpItemFor[1];
break;
case 1: strInp = udpItemFor[1];
break;
case 2: strOutp = udpItemFor[1];
break;
case 4: strFeedBack = udpItemFor[1];
break;
case 37: strTotal_E = udpItemFor[1];
break;
case 5: strA_Current = udpItemFor[1];
break;
case 17: strAB_Voltage = udpItemFor[1];
break;
case 8: strA_Current2 = udpItemFor[1];
break;
case 20: strAB_Voltage2 = udpItemFor[1];
break;
case 42: No1M_Run = udpItemFor[1];
break;
case 45: No2M_Run = udpItemFor[1];
break;
}
}
//UDPItem1 = UDPItems[1].Split(Colon);
//UDPItem2 = UDPItems[2].Split(Colon);
//UDPItemFeedBack = UDPItems[3].Split(Colon);
//UDPItemTotal_E = UDPItems[8].Split(Colon);
//UDPItemA_Current = UDPItems[4].Split(Colon);
//UDPItemAB_Voltage = UDPItems[6].Split(Colon);
if (UDPItem0.Length > 0)
{
//string valueStr = "设压:" + strSetp + "|进压:" + strInp + "|出压:" + strOutp;
//string recstring2 = recString.Substring(recString.IndexOf(',') + 1);
Console.WriteLine("No:" + UDPItem0[0] + "设压:" + strSetp + "|进压:" + strInp + "|出压:" + strOutp + "|OPC时间:" + mat.Groups[1] + ":");
//string recString3 = recstring2.Substring(0, recstring2.IndexOf(':'));
objhelper.UpdateSql(conn, UDPItem0[0], strSetp, strInp, strOutp, mat.Groups[1].ToString(), strFeedBack, strTotal_E, strA_Current, strAB_Voltage, strA_Current2, strAB_Voltage2, No1M_Run, No2M_Run);
}
}
}
PostRecv(state.EndPoint);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
PostRecv(state.EndPoint);
}
// PostSend(state.Buffer, state.Offset, state.Size, state.EndPoint);
}
private static void EndSend(IAsyncResult asyncResult)
{
AsyncState state = (AsyncState)asyncResult.AsyncState;
byte[] buffer = state.Buffer;
int sendBytes = m_sListen.EndSendTo(asyncResult);
int remainBytes = state.Size - sendBytes;
if (remainBytes <= 0)
return;
PostSend(buffer, buffer.Length - remainBytes, remainBytes, state.EndPoint);
}
[Serializable, StructLayout(LayoutKind.Sequential)]
internal struct AsyncState
{
private readonly byte[] buffer;
private readonly int offset;
private readonly int size;
public AsyncState(byte[] buffer, EndPoint endPoint)
{
if (endPoint == null)
{
throw new ArgumentNullException("endPoint");
}
this.buffer = buffer;
this.offset = 0;
this.size = buffer.Length;
this.EndPoint = endPoint;
}
public AsyncState(byte[] buffer, int offset, int size, EndPoint endPoint)
{
if (buffer == null)
{
throw new ArgumentNullException("array");
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException("offset", "ArgumentOutOfRange_NeedNonNegNum");
}
if (size < 0)
{
throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_NeedNonNegNum");
}
if ((buffer.Length - offset) < size)
{
throw new ArgumentException("Argument_InvalidOffLen");
}
if (endPoint == null)
{
throw new ArgumentNullException("endPoint");
}
this.buffer = buffer;
this.offset = offset;
this.size = size;
this.EndPoint = endPoint;
}
public byte[] Buffer
{
get { return buffer; }
}
public int Offset
{
get { return offset; }
}
public int Size
{
get { return size; }
}
public EndPoint EndPoint;
}
这是我写的一个UPDserver接受你可以参考参考,数据量不小
#9
感觉使用UDP丢包很难避免啊
#10
换个协议吧。
试试rtp
试试rtp
#11
谢谢你的代码,但是有点看不懂啊
#12
UDP是不可靠的传输方式
#13
我知道,但是这里必须用到UDP,如果用TCP我也就没这问题了
#15
允许丢包的场景才会UDP。比如游戏里面的走动。即使丢几个包。也不要紧。
#16
还有就知道为什么丢包。是发的数据量超过上行,接收超过了下行,3G,WIFI的时候是不是信息号不好。还是TTL太大。
#17
我自己做了个测试
让发送端一次性发送300条信息过来 我发现在接收的端口上只能收到几十个,而且我已经把对接收到的信息处理程序停掉,只是单纯的接收,想问下有没有方法能够增强端口接收大数据的能力啊
让发送端一次性发送300条信息过来 我发现在接收的端口上只能收到几十个,而且我已经把对接收到的信息处理程序停掉,只是单纯的接收,想问下有没有方法能够增强端口接收大数据的能力啊
#18
兄弟,先不说UDP丢包情况,你还需要考虑的一个问题就是Socket接收缓冲区是否溢出。因为你用的是TextBox类增方式这个累计以后耗时还是有点长的。为什么一丢失信息就考虑丢包呢?就不考虑是否溢出?UDP与TCP比确实不可靠一些,但是在我测试这么久以来还是感觉挺稳定的。至少在局域网里面是的。
#1
udp本来就是不可靠通讯。
你知道有个tcp么?
tcp才是可靠的通讯(之一)。
你知道有个tcp么?
tcp才是可靠的通讯(之一)。
#2
“看程序”没有多大意义,因为连基本的教科书上的概念都保证说“udp丢包是非常正常、非常普遍的”。你可以多看两小本通讯方面的入门书即可有所收获。
#3
UDP本来就是允许丢包的,所以一般运用在视频中~就是卡一下,画面模糊一下也没有关系~
不允许丢包的场景 请用TCP
不允许丢包的场景 请用TCP
#4
各位大神们都发言了,,偶也来围观。。。。
#5
我是在本机上进行通信,我当然知道TCP
#6
UDP是在大量传输数据的时候允许丢包,一般用在视频上。
TCP有握手协议,所以不会丢包,很可靠,但是效率稍微有点低。
TCP有握手协议,所以不会丢包,很可靠,但是效率稍微有点低。
#7
单向传输必须用UPD,因为很多工业现场直接物理隔离了双向传输
#8
LZ可以改异步试试,比多线程效率高
这是我写的一个UPDserver接受你可以参考参考,数据量不小
static DataTable dt;
static DataTable Abbdt;
static SqlHelper objhelper;
static SqlConnection conn;
static OtherClass oc;
// Attributes
private ArrayList m_aryClients = new ArrayList(); // List of Client Connections
public const string GaoxinUDPProtocol = @"FDFDV\d.\d{2}.\d{2}L\d{3}DT(2\d\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])\s+\d{2}:\d{2}:\d{2}),(.*)FEFE";
public const string GaoxinUDPData = @"^[0-9]*:[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?:[0-9]*$";
public const char Comma = ',';
public const char Colon = ':';
static Regex reg;
static Regex dataReg;
/// <summary>
/// Application starts here. Create an instance of this class and use it
/// as the main object.
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
objhelper = new SqlHelper();
conn = objhelper.getConn();
conn.Open();
oc = new OtherClass();
reg = new Regex(GaoxinUDPProtocol);
dataReg = new Regex(GaoxinUDPData);
int nPortListen = oc.lPort();
IPAddress ip = IPAddress.Parse(oc.IPAddress());
IPAddress ipAny = IPAddress.Any;
IPEndPoint ipe = new IPEndPoint(ip, nPortListen);
m_sListen = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
m_sListen.Bind(ipe);
//IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
//EndPoint remote = (EndPoint)sender;
EndPoint remote = (EndPoint)ipe;
PostRecv(ipe);
Console.WriteLine("请按回车键结束!");
Console.ReadKey();
conn.Close();
GC.Collect();
GC.WaitForPendingFinalizers();
}
#region UDP
static Socket m_sListen;
private static void ListenThreadMothed()
{
}
private static void PostRecv(EndPoint endPoint)
{
byte[] buffer = new byte[1048576];
m_sListen.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref endPoint, EndRecv, new AsyncState(buffer, 0, buffer.Length, endPoint));
}
private static void PostSend(byte[] buffer, int offset, int size, EndPoint endPoint)
{
m_sListen.BeginSendTo(buffer,
offset,
size,
SocketFlags.None,
endPoint,
EndSend,
new AsyncState(buffer, offset, size, endPoint));
}
private static void EndRecv(IAsyncResult asyncResult)
{
AsyncState state = (AsyncState)asyncResult.AsyncState;
try
{
m_sListen.EndReceiveFrom(asyncResult, ref state.EndPoint);
if (state.Buffer.Length > 20)
{
string recString = System.Text.Encoding.Default.GetString(state.Buffer);
string[] UDPItems;
string[] UDPItem0;
string strSetp = "0", strInp = "0", strOutp = "0", strFeedBack = "0", strTotal_E = "0", strA_Current = "0", strAB_Voltage = "0", strA_Current2 = "0", strAB_Voltage2 = "0", No1M_Run = "0", No2M_Run = "0";
Match mat = reg.Match(recString.Trim(), 0);
//recString.IndexOf(',');
//recString.IndexOf(':');
if (mat.Success)
{
UDPItems = mat.Groups[4].Value.Split(Comma);
string[] udpItemFor;
UDPItem0 = UDPItems[0].Split(Colon);
int intNO = int.Parse(UDPItem0[0]);
foreach (var item in UDPItems)
{
udpItemFor = item.Split(Colon);
int strNO = int.Parse(udpItemFor[0]);
if (strNO - intNO >= 80)
{
break;
}
int theV = strNO % 80;
switch (theV)
{
case 0: strSetp = udpItemFor[1];
break;
case 1: strInp = udpItemFor[1];
break;
case 2: strOutp = udpItemFor[1];
break;
case 4: strFeedBack = udpItemFor[1];
break;
case 37: strTotal_E = udpItemFor[1];
break;
case 5: strA_Current = udpItemFor[1];
break;
case 17: strAB_Voltage = udpItemFor[1];
break;
case 8: strA_Current2 = udpItemFor[1];
break;
case 20: strAB_Voltage2 = udpItemFor[1];
break;
case 42: No1M_Run = udpItemFor[1];
break;
case 45: No2M_Run = udpItemFor[1];
break;
}
}
//UDPItem1 = UDPItems[1].Split(Colon);
//UDPItem2 = UDPItems[2].Split(Colon);
//UDPItemFeedBack = UDPItems[3].Split(Colon);
//UDPItemTotal_E = UDPItems[8].Split(Colon);
//UDPItemA_Current = UDPItems[4].Split(Colon);
//UDPItemAB_Voltage = UDPItems[6].Split(Colon);
if (UDPItem0.Length > 0)
{
//string valueStr = "设压:" + strSetp + "|进压:" + strInp + "|出压:" + strOutp;
//string recstring2 = recString.Substring(recString.IndexOf(',') + 1);
Console.WriteLine("No:" + UDPItem0[0] + "设压:" + strSetp + "|进压:" + strInp + "|出压:" + strOutp + "|OPC时间:" + mat.Groups[1] + ":");
//string recString3 = recstring2.Substring(0, recstring2.IndexOf(':'));
objhelper.UpdateSql(conn, UDPItem0[0], strSetp, strInp, strOutp, mat.Groups[1].ToString(), strFeedBack, strTotal_E, strA_Current, strAB_Voltage, strA_Current2, strAB_Voltage2, No1M_Run, No2M_Run);
}
}
}
PostRecv(state.EndPoint);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
PostRecv(state.EndPoint);
}
// PostSend(state.Buffer, state.Offset, state.Size, state.EndPoint);
}
private static void EndSend(IAsyncResult asyncResult)
{
AsyncState state = (AsyncState)asyncResult.AsyncState;
byte[] buffer = state.Buffer;
int sendBytes = m_sListen.EndSendTo(asyncResult);
int remainBytes = state.Size - sendBytes;
if (remainBytes <= 0)
return;
PostSend(buffer, buffer.Length - remainBytes, remainBytes, state.EndPoint);
}
[Serializable, StructLayout(LayoutKind.Sequential)]
internal struct AsyncState
{
private readonly byte[] buffer;
private readonly int offset;
private readonly int size;
public AsyncState(byte[] buffer, EndPoint endPoint)
{
if (endPoint == null)
{
throw new ArgumentNullException("endPoint");
}
this.buffer = buffer;
this.offset = 0;
this.size = buffer.Length;
this.EndPoint = endPoint;
}
public AsyncState(byte[] buffer, int offset, int size, EndPoint endPoint)
{
if (buffer == null)
{
throw new ArgumentNullException("array");
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException("offset", "ArgumentOutOfRange_NeedNonNegNum");
}
if (size < 0)
{
throw new ArgumentOutOfRangeException("count", "ArgumentOutOfRange_NeedNonNegNum");
}
if ((buffer.Length - offset) < size)
{
throw new ArgumentException("Argument_InvalidOffLen");
}
if (endPoint == null)
{
throw new ArgumentNullException("endPoint");
}
this.buffer = buffer;
this.offset = offset;
this.size = size;
this.EndPoint = endPoint;
}
public byte[] Buffer
{
get { return buffer; }
}
public int Offset
{
get { return offset; }
}
public int Size
{
get { return size; }
}
public EndPoint EndPoint;
}
这是我写的一个UPDserver接受你可以参考参考,数据量不小
#9
感觉使用UDP丢包很难避免啊
#10
换个协议吧。
试试rtp
试试rtp
#11
谢谢你的代码,但是有点看不懂啊
#12
UDP是不可靠的传输方式
#13
我知道,但是这里必须用到UDP,如果用TCP我也就没这问题了
#14
#15
允许丢包的场景才会UDP。比如游戏里面的走动。即使丢几个包。也不要紧。
#16
还有就知道为什么丢包。是发的数据量超过上行,接收超过了下行,3G,WIFI的时候是不是信息号不好。还是TTL太大。
#17
我自己做了个测试
让发送端一次性发送300条信息过来 我发现在接收的端口上只能收到几十个,而且我已经把对接收到的信息处理程序停掉,只是单纯的接收,想问下有没有方法能够增强端口接收大数据的能力啊
让发送端一次性发送300条信息过来 我发现在接收的端口上只能收到几十个,而且我已经把对接收到的信息处理程序停掉,只是单纯的接收,想问下有没有方法能够增强端口接收大数据的能力啊
#18
兄弟,先不说UDP丢包情况,你还需要考虑的一个问题就是Socket接收缓冲区是否溢出。因为你用的是TextBox类增方式这个累计以后耗时还是有点长的。为什么一丢失信息就考虑丢包呢?就不考虑是否溢出?UDP与TCP比确实不可靠一些,但是在我测试这么久以来还是感觉挺稳定的。至少在局域网里面是的。