接收SOCKET消息的时候弹出多次消息(不好描述,看代码吧)

wang520d 2009-06-19 06:15:08


/// <summary>
/// 提取命令
/// 格式为两个一位整数拼接成的字符串。
/// 第一位为0表示客户机向服务器发送的命令,为1表示服务器向客户机发送的命令。
/// 第二位表示命令的含义,具体如下:
/// "11"-服务器要求客户机更新在线列表
/// "12"-服务器要求客户机做闪屏振动
/// default-接受用户消息或者系统消息的正文
/// </summary>
/// <param name="s">要解析的包含命令的byte数组,只提取前两个字节</param>
/// <returns>拼接成的命令</returns>
private string DecodingBytes(byte[] s)
{
return string.Concat(s[0].ToString(), s[1].ToString());
}

/// <summary>
/// 接受消息的线程执行体
/// </summary>
private void ReceiveMsg()
{

try
{
while (true)
{
byte[] packet = new byte[_maxPacket];
_nws.Read(packet, 0, packet.Length);
string _cmd = DecodingBytes(packet);

switch (_cmd)
{
/// "11"-服务器要求客户机更新在线列表
/// "12"-服务器要求客户机做闪屏振动
/// default-接受用户消息或者系统消息的正文
case "11":
{
byte[] onlineBuff = new byte[_maxPacket];
int byteCnt = _nws.Read(onlineBuff, 0, onlineBuff.Length);
IFormatter format = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
stream.Write(onlineBuff, 0, byteCnt);
stream.Position = 0;
StringCollection onlineList = (StringCollection)format.Deserialize(stream);
online_cb.Items.Clear();
foreach (string onliner in onlineList)
{
if (!onliner.Equals(_username))
{
online_cb.Items.Add(onliner);
}
}
break;
}
case "12":
{
Nudge();
break;
}
default:
{
string displaytxt = Encoding.Unicode.GetString(packet);
chatrcd_rtb.AppendText(displaytxt);
//消息是空格时好像也会进来。。。怎么处理这里
if (!string.IsNullOrEmpty(displaytxt))
{
//AlertMsg(displaytxt);
Client.Msg.MsgMain mm = new Client.Msg.MsgMain();
Client.Msg.MsgMain.formClassFullPath = "Client.Mission.TelMissions";
Client.Msg.MsgMain.msgContent = displaytxt.Trim();
mm.Show();
_sp1.Play();
}

break;
}
}
}
}
catch (Exception err)
{
Clscommonuse.WriteError("接受消息的线程执行体ChatForm-ReceiveMsg()", "ReceiveMsg", err.Source, err.Message);
}
}

...全文
223 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
homesos 2009-07-03
  • 打赏
  • 举报
回复
具体可以查阅一下MSDN,给个小示例:

private Thread socketThread; //读取SOCKET数据的线程
private bool bRunSocket = false;

/// <summary>
/// 启动socket客户端
/// </summary>
/// <returns></returns>
public int OnStartSocketClient()
{
if (!bRunSocket)
{
bRunSocket = true;
socketThread = new Thread(new ThreadStart(OnReadFromServer));
socketThread.Start();
}
return 0;
}

/// <summary>
/// 连接socket服务器端,并接收数据
/// </summary>
private void OnReadFromServer()
{
}
wang520d 2009-06-26
  • 打赏
  • 举报
回复
还是不知道该怎么加入子线程处理
wang520d 2009-06-24
  • 打赏
  • 举报
回复
问题变了,现在我用TRMEND去掉后面所有空格匹配项后还是一样 无法正常打开那个窗体 每次打开页面都无法响应状态,后来在网上搜索了下:
while为真始终循环,没有等到接收新数据就已经开始循环了,所以displaytxt里面没有值,所以会显示出空的messagebox,理论上应该是不会停止的,除非你停止调试了。建议修改while结构

那么怎么改写这个WHILE循环呢?
homesos 2009-06-24
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 dhtkhnt 的回复:]
接收使用新的线程.
[/Quote]
对,要使用子线程进行接收、处理数据,LZ不会在主线程中直接处理的吧,这样窗口肯定会没有响应的,因为有个WHILE死循环不停在那跑
dhtkhnt 2009-06-24
  • 打赏
  • 举报
回复
接收使用新的线程.
homesos 2009-06-24
  • 打赏
  • 举报
回复
不符合你想要的条件的,都不处理。
homesos 2009-06-24
  • 打赏
  • 举报
回复
1.判断从网络接收的数据长度
2.对字符串进行Trim()去掉前后空格
wang520d 2009-06-24
  • 打赏
  • 举报
回复
default:
{
string displaytxt = Encoding.Unicode.GetString(packet);
chatrcd_rtb.AppendText(displaytxt);
//消息是空格时好像也会进来。。。怎么处理这里
if (!string.IsNullOrEmpty(displaytxt))
{
//AlertMsg(displaytxt);
Client.Msg.MsgMain mm = new Client.Msg.MsgMain();
Client.Msg.MsgMain.formClassFullPath = "Client.Mission.TelMissions";
Client.Msg.MsgMain.msgContent = displaytxt.Trim();
mm.Show();
_sp1.Play();
}

break;
}
我这就是这么接收的啊。。
homesos 2009-06-24
  • 打赏
  • 举报
回复
你的while循环,没有退出部分?


while (g_bWork)
{
}



while (true)
{
//从网络接收数据失败之类
break;
}

homesos 2009-06-24
  • 打赏
  • 举报
回复
从网络接收数据转成字符串,的确需要按下面代码的来做:

int readLength = _nws.Read(packet, 0, packet.Length);

...

string displaytxt = Encoding.Unicode.GetString(packet, 0, readLength);
//或者用
string displaytxt = System.Text.Encoding.Default.GetString(packet, 0, readLength);
homesos 2009-06-24
  • 打赏
  • 举报
回复
Read是阻塞模式,还是非阻塞模式?
wang520d 2009-06-24
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 homesos 的回复:]
C/C++ code
byte[] packet = new byte[_maxPacket];
memeset(packet, 0, _maxPacket); //加一下这个试试
_nws.Read(packet, 0, packet.Length);
[/Quote]

这个我也是加了的

byte[] packet = new byte[_maxPacket];
_nws.Read(packet, 0, packet.Length);
string _cmd = DecodingBytes(packet);


关键是WHILE循环。。。
homesos 2009-06-24
  • 打赏
  • 举报
回复

int readLength = _nws.Read(packet, 0, packet.Length); //接收不到数据也往下走?那就判断readLength
homesos 2009-06-24
  • 打赏
  • 举报
回复
晕,搞错了,还以为是C++呢……
homesos 2009-06-24
  • 打赏
  • 举报
回复

byte[] packet = new byte[_maxPacket];
memeset(packet, 0, _maxPacket); //加一下这个试试
_nws.Read(packet, 0, packet.Length);
wang520d 2009-06-24
  • 打赏
  • 举报
回复
期待有人帮忙指点下。。。
gongsun 2009-06-24
  • 打赏
  • 举报
回复
...
wang520d 2009-06-24
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 homesos 的回复:]
引用 19 楼 dhtkhnt 的回复:
接收使用新的线程.


对,要使用子线程进行接收、处理数据,LZ不会在主线程中直接处理的吧,这样窗口肯定会没有响应的,因为有个WHILE死循环不停在那跑
[/Quote]
还真是在主线程中直接处理的数据。。。
满衣兄 2009-06-22
  • 打赏
  • 举报
回复
加个包尾
wang520d 2009-06-19
  • 打赏
  • 举报
回复
网上GOOGLE到的一些说法

错误原因:NetworkStream接受过来的Byte[]不一定占满packet数组的,packet数组后面有剩余,因此你用Encoding.Unicode.GetString(packet); 返回的string一定有错误。

解决方案:
NetworkStream.Read返回一个int来指示有效地读入字节数,当然这个字节数是<=packet.Length,用这个是来返回正确的字符串。

int readLength = _nws.Read(packet, 0, packet.Length);

...

string displaytxt = Encoding.Unicode.GetString(packet, 0, readLength);

加载更多回复(3)
内容概要:本文围绕间歇性光伏出力条件下48V直流母线电压的稳定控制与储能系统双向充放电的闭环调控体系展开深入研究,系统探讨了光伏阵列非线性输出特性与锂离子电池储能系统在离网直流微网中的能量均衡建模方法及分层控制策略。通过Simulink平台构建完整的光伏储能直流系统仿真模型,涵盖PV阵列、Boost DC-DC变换器、负载、双向DC-DC变换器及电池系统等关键组件,实现了最大功率点跟踪(MPPT)与储能系统的协同控制,有效应对光照波动引起的功率供需失衡问题。研究采用双PI闭环控制、模型预测控制(MPC)等多种先进控制算法,显著提升了系统的动态响应速度与直流母线电压稳定性,并实现了储能系统在削峰填谷中的优化运行,对于增强离网微网的供电可靠性与能源利用效率具有重要理论价值和工程意义。; 适合人群:具备电力电子、新能源系统或自动控制等相关领域基础知识的研究生、科研人员,以及从事微电网、光伏储能系统开发与设计的工程技术人员。; 使用场景及目标:① 构建适用于离网场景的光伏储能系统Simulink仿真模型;② 实现间歇性光照条件下48V直流母线电压的精确稳定控制与储能系统的双向能量管理;③ 研究MPPT控制与储能充放电策略之间的协同机制,提升系统在复杂工况下的运行稳定性与鲁棒性;④ 为微电网能量管理系统的设计、优化与性能验证提供可靠的理论依据和技术支撑。; 阅读建议:建议结合文中所述的Simulink仿真模型与控制算法,亲自动手实践建模与仿真全过程,重点关注MPPT控制策略的实现、双向DC-DC变换器的设计以及电压外环与电流内环构成的双闭环控制结构的参数整定,并通过设置不同的光照强度变化曲线和负载投切工况,全面测试和评估系统的动态响应能力与控制性能。

62,272

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

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