C# 客户端网络通讯代码一则,请指点是否有不足之处 本帖最后由 zhaoxiuyong 于 2014-10-09 11:08:15 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 /// <summary> /// 发送注册包 /// </summary> public void SendRegisterPackage(string reg) { this.tcpClient.Client.Send(Encoding.ASCII.GetBytes(reg)); } /// <summary> /// 开始接收数据 /// </summary> public void StartReceiveData() { if (this.tcpClient.Connected) { try { isStop = true; thread = new Thread(new ThreadStart(ReceiveData)); thread.Start(); } catch (Exception e) {} } } /// <summary> /// 发送指令到服务器 /// </summary> /// <param name="command">指令</param> public void SendCommand(string command) { this.netSrteam.Write(Encoding.Default.GetBytes(command), 0, Encoding.Default.GetBytes(command).Length); } /// <summary> /// 发送指令到服务器 /// </summary> /// <param name="command">指令</param> public bool SendCommand(byte[] command) { try { if (!this.tcpClient.Connected) return false; this.netSrteam.Write(command, 0, command.Length); return true; } catch { return false; } } private void ReceiveData() { while (isStop) { if (this.tcpClient.Connected) { if (netSrteam.CanRead && netSrteam.DataAvailable) { try { int itype = byteRead.ReadInt32(); byte[] length = BitConverter.GetBytes(itype); if (itype == monLen) { byte[] data = new byte[monLen]; length.CopyTo(data, 0); byte[] temp = byteRead.ReadBytes(monLen - length.Length); temp.CopyTo(data, length.Length); if (this.OnUpdateData != null) { this.OnUpdateData.BeginInvoke(data, null, null); } if (this.OnUpdateDataForEmph != null) { this.OnUpdateDataForEmph.BeginInvoke(data, null, null); } } else { if (this.OnReceiveCatch != null) { this.OnReceiveCatch.BeginInvoke(string.Format("接收到非标准数据长度数据{0}", itype), byteRead.ReadBytes(itype), null, null); } } } catch (Exception e) { if (this.OnReceiveCatch != null) { this.OnReceiveCatch.BeginInvoke(string.Format("接收数据发生异常{0}", e.ToString()), null, null, null); } } } } Thread.Sleep(20); } } /// <summary> /// byte数组转结构体 /// </summary> /// <param name="bytes">byte数组</param> /// <param name="type">结构体类型</param> /// <returns>转换后的结构体</returns> public static object BytesToStuct(byte[] bytes, Type type) { try { //得到结构体的大小 int size = Marshal.SizeOf(type); //byte数组长度小于结构体的大小 if (size > bytes.Length) { //返回空 return null; } //分配结构体大小的内存空间 IntPtr structPtr = Marshal.AllocHGlobal(size); //将byte数组拷到分配好的内存空间 Marshal.Copy(bytes, 0, structPtr, size); //将内存空间转换为目标结构体 object obj = Marshal.PtrToStructure(structPtr, type); //释放内存空间 Marshal.FreeHGlobal(structPtr); //返回结构体 return obj; } catch { return null; } } }}窗口调用代码在Form_Load()事件中 //绑定接收数据触发事件 _updateMonitorData = new Communicate.UpdateDataForEmph(Instance_OnUpdateDataForEmph); Communicate.Instance.OnUpdateDataForEmph += _updateMonitorData; GATHERDATAEXTEND mon = new GATHERDATAEXTEND(); //获取服务器地址和端口 string strServer = BasicSettingComm.GetSettingByName("MonitorServer"); int iPort = Convert.ToInt32(BasicSettingComm.GetSettingByName("MonitorServerPort")); //初始化通讯连接 Communicate.Instance.Init(strServer, iPort, System.Runtime.InteropServices.Marshal.SizeOf(mon), 20); //绑定与服务器连接断开事件 Communicate.Instance.OnServerConnectAbort += new Communicate.ServerConnectAbort(Instance_OnServerConnectAbort); _updateMonitorData = new Communicate.UpdateDataForEmph(Instance_OnUpdateDataForEmph); //开始连接服务器 MethodInvoker mi = delegate { Connect(); }; mi.BeginInvoke(null, null);/// <summary> /// 连接通讯服务器 /// </summary> private void Connect() { System.Globalization.CultureInfo cultInfo = System.Globalization.CultureInfo.CurrentUICulture; bool conn = Communicate.Instance.ConnectServer(string.Format(BasicSettingComm.Instance.regCommand, Context.UserId), string.Format(BasicSettingComm.Instance.heartbeat, Context.UserId)); if (conn)//连接服务器成功 { Communicate.Instance.StartReceiveData(); } else { if (cultInfo.Name.ToLower() == "en") ServiceConnectAbort("Server's service donot runing."); else ServiceConnectAbort("无法连接监护服务器"); } } //与服务器连接断开事件 void Instance_OnServerConnectAbort() { ServiceConnectAbort(null); } System.Threading.Timer time = null; private void ServiceConnectAbort(string txt) { if (!object.Equals(txt, null)) { Common.ShowInfoMess(txt); } //与服务器连接断开后启动定时重连服务器 time = new System.Threading.Timer(new TimerCallback(time_Tick), null, 2000, 20000); } //定时重连服务器 void time_Tick(object o) { bool conn = Communicate.Instance.ConnectServer(string.Format(BasicSettingComm.Instance.regCommand, Context.UserId), string.Format(BasicSettingComm.Instance.heartbeat, Context.UserId)); if (conn) { Communicate.Instance.StartReceiveData(); time.Dispose(); } Thread.Sleep(50); } 窗口关闭时注销连接,Form_Closing事件中Communicate.Instance.OnUpdateDataForEmph -= _updateMonitorData; Communicate.Instance.Dispose(); 这是什么年代的了...现在最起码的 异步应该有吧 性能最少比你所谓的while(true)不知道高了多少倍socketasynceventargs就更不用说了.. 而且 既然作为tcpclient 无非就是连接(不是很是重要),发送,接收 主要在于后面2个代码..而且基于是client 也不需要考虑并发多线程什么的..应该不是很难写...你这代码似乎太多了. 好长!楼主是来分享代码的吗想知道是否有大的缺陷,写个伪代码,提供个思路就行了想知道是否有具体的BUG,还是得自己测试,没人会帮你做测试 本来想当个好人的,结果看到你用的是tcpclient,我无能为力了,socket还好,这个真不行 c# https 验证的问题 lucene里面多条件查询的问题,急等 小菜求教,遇到一个让我很尴尬的问题 c#操作excel--怎样在sheet 里指定行位置插入新行 visual studio 2005下的分页 大家有没有把excel导入数据库的c#代码阿?? 高手关注:在IE中使用windows控件出现异常 帮帮我!!! 在CrystalReports中,怎么在同一页上显示多条记录 请问那有c#+ado.net的实例程序源代码或c#+ado.net程序下载 Unity缓冲池技术 一个有趣的技术,请问怎么实现!
/// 发送注册包
/// </summary>
public void SendRegisterPackage(string reg)
{
this.tcpClient.Client.Send(Encoding.ASCII.GetBytes(reg));
} /// <summary>
/// 开始接收数据
/// </summary>
public void StartReceiveData()
{
if (this.tcpClient.Connected)
{
try
{
isStop = true;
thread = new Thread(new ThreadStart(ReceiveData));
thread.Start();
}
catch (Exception e) {}
}
}
/// <summary>
/// 发送指令到服务器
/// </summary>
/// <param name="command">指令</param>
public void SendCommand(string command)
{
this.netSrteam.Write(Encoding.Default.GetBytes(command), 0, Encoding.Default.GetBytes(command).Length);
} /// <summary>
/// 发送指令到服务器
/// </summary>
/// <param name="command">指令</param>
public bool SendCommand(byte[] command)
{
try
{
if (!this.tcpClient.Connected) return false;
this.netSrteam.Write(command, 0, command.Length);
return true;
}
catch { return false; }
}
private void ReceiveData()
{
while (isStop)
{
if (this.tcpClient.Connected)
{
if (netSrteam.CanRead && netSrteam.DataAvailable)
{
try
{
int itype = byteRead.ReadInt32();
byte[] length = BitConverter.GetBytes(itype);
if (itype == monLen)
{
byte[] data = new byte[monLen];
length.CopyTo(data, 0);
byte[] temp = byteRead.ReadBytes(monLen - length.Length);
temp.CopyTo(data, length.Length); if (this.OnUpdateData != null)
{
this.OnUpdateData.BeginInvoke(data, null, null);
}
if (this.OnUpdateDataForEmph != null)
{
this.OnUpdateDataForEmph.BeginInvoke(data, null, null);
}
}
else
{
if (this.OnReceiveCatch != null)
{
this.OnReceiveCatch.BeginInvoke(string.Format("接收到非标准数据长度数据{0}", itype), byteRead.ReadBytes(itype), null, null);
}
}
}
catch (Exception e)
{
if (this.OnReceiveCatch != null)
{
this.OnReceiveCatch.BeginInvoke(string.Format("接收数据发生异常{0}", e.ToString()), null, null, null);
}
}
}
}
Thread.Sleep(20);
}
} /// <summary>
/// byte数组转结构体
/// </summary>
/// <param name="bytes">byte数组</param>
/// <param name="type">结构体类型</param>
/// <returns>转换后的结构体</returns>
public static object BytesToStuct(byte[] bytes, Type type)
{
try
{
//得到结构体的大小
int size = Marshal.SizeOf(type);
//byte数组长度小于结构体的大小
if (size > bytes.Length)
{
//返回空
return null;
}
//分配结构体大小的内存空间
IntPtr structPtr = Marshal.AllocHGlobal(size);
//将byte数组拷到分配好的内存空间
Marshal.Copy(bytes, 0, structPtr, size);
//将内存空间转换为目标结构体
object obj = Marshal.PtrToStructure(structPtr, type);
//释放内存空间
Marshal.FreeHGlobal(structPtr);
//返回结构体
return obj;
}
catch { return null; }
}
}
}
窗口调用代码
在Form_Load()事件中 //绑定接收数据触发事件
_updateMonitorData = new Communicate.UpdateDataForEmph(Instance_OnUpdateDataForEmph);
Communicate.Instance.OnUpdateDataForEmph += _updateMonitorData; GATHERDATAEXTEND mon = new GATHERDATAEXTEND(); //获取服务器地址和端口
string strServer = BasicSettingComm.GetSettingByName("MonitorServer");
int iPort = Convert.ToInt32(BasicSettingComm.GetSettingByName("MonitorServerPort")); //初始化通讯连接
Communicate.Instance.Init(strServer, iPort, System.Runtime.InteropServices.Marshal.SizeOf(mon), 20); //绑定与服务器连接断开事件
Communicate.Instance.OnServerConnectAbort += new Communicate.ServerConnectAbort(Instance_OnServerConnectAbort);
_updateMonitorData = new Communicate.UpdateDataForEmph(Instance_OnUpdateDataForEmph); //开始连接服务器
MethodInvoker mi = delegate { Connect(); };
mi.BeginInvoke(null, null);/// <summary>
/// 连接通讯服务器
/// </summary>
private void Connect()
{
System.Globalization.CultureInfo cultInfo = System.Globalization.CultureInfo.CurrentUICulture;
bool conn = Communicate.Instance.ConnectServer(string.Format(BasicSettingComm.Instance.regCommand, Context.UserId), string.Format(BasicSettingComm.Instance.heartbeat, Context.UserId));
if (conn)//连接服务器成功
{
Communicate.Instance.StartReceiveData();
}
else
{
if (cultInfo.Name.ToLower() == "en") ServiceConnectAbort("Server's service donot runing.");
else
ServiceConnectAbort("无法连接监护服务器");
}
} //与服务器连接断开事件
void Instance_OnServerConnectAbort()
{
ServiceConnectAbort(null);
} System.Threading.Timer time = null;
private void ServiceConnectAbort(string txt)
{
if (!object.Equals(txt, null))
{
Common.ShowInfoMess(txt);
} //与服务器连接断开后启动定时重连服务器
time = new System.Threading.Timer(new TimerCallback(time_Tick), null, 2000, 20000);
} //定时重连服务器
void time_Tick(object o)
{
bool conn = Communicate.Instance.ConnectServer(string.Format(BasicSettingComm.Instance.regCommand, Context.UserId), string.Format(BasicSettingComm.Instance.heartbeat, Context.UserId));
if (conn)
{
Communicate.Instance.StartReceiveData();
time.Dispose();
}
Thread.Sleep(50);
}
Communicate.Instance.OnUpdateDataForEmph -= _updateMonitorData;
Communicate.Instance.Dispose();
socketasynceventargs就更不用说了..
楼主是来分享代码的吗想知道是否有大的缺陷,写个伪代码,提供个思路就行了
想知道是否有具体的BUG,还是得自己测试,没人会帮你做测试