📄 如何写一个稳定,高效的socket服务器程序。 _net技术 - c# - csdn社区 community_csdn_net.htm
字号:
Console.WriteLine(e.Message+","+sFileName); <BR> byOper =
OPEN_FILE_FAILED; <BR> } <BR> <BR>
//组织回应命令 <BR> pos = 0; <BR> <BR>
m_byte.SetWord(bSend,CMD_S_REQUERY,ref pos); <BR>
<BR> m_byte.SetByte(bSend,new byte[]{byOper},ref pos);
<BR> <BR>
theSockId.thisSocket.Send(bSend,0,pos,SocketFlags.None );
<BR> <BR> <BR> } <BR> else
if(nCmd == CMD_C_DETAIL) //detail <BR> {
<BR> <BR> // Console.WriteLine("Recevied file
detail info {0} times",nCurTime); <BR> //
assert m_file is opened <BR>
if(theSockId.m_file == null) <BR> return ;
<BR> //close <BR> theSockId.nCurTime =
m_byte.GetDword(theSockId.dataBuffer,ref pos); <BR>
<BR> theSockId.m_file.Write(theSockId.dataBuffer, pos,iRx -
pos); <BR> <BR> //每十个包保存一次 <BR>
if((theSockId.nCurTime /10 ) == 0) <BR>
//save <BR> theSockId.m_file.Flush(); <BR>
<BR> //组织回应命令 <BR> pos = 0; <BR>
<BR> m_byte.SetWord(bSend,CMD_S_DETAIL,ref pos); <BR>
m_byte.SetDword(bSend,theSockId.nCurTime,ref pos); <BR>
theSockId.thisSocket.Send(bSend,0,pos,SocketFlags.None); <BR>
<BR> if( theSockId.nCurTime ==
theSockId.nTimes ) <BR> { <BR> //save
<BR> theSockId.m_file.Flush(); <BR> theSockId.m_file.Close();
<BR> theSockId.m_file = null; <BR> theSockId.nTimes =
0; <BR> // sFileName= null; <BR> } <BR>
<BR> } <BR> WaitForData(nIndex );
<BR> <BR> } <BR> <BR> // catch
(ObjectDisposedException ) <BR> // {
<BR> // System.Diagnostics.Debugger.Log(0,"1","\nOnDataReceived:
Socket has been closed\n"); <BR> // }
<BR> <BR> catch(SocketException se) <BR>
{ <BR> ProcessSocketException(se,nIndex); <BR>
<BR> } <BR> <BR> } <BR>
<BR> <BR> /// <summary> <BR> ///
接受新连接,并保存到连接数组 <BR> /// </summary>
<BR> /// <param name="ar"></param>
<BR> private void OnAccept(IAsyncResult ar)
<BR> { <BR> try <BR> { <BR> Socket
sWait = (Socket)ar.AsyncState; <BR> //new
connect socket <BR> Socket sNew =
sWait.EndAccept(ar); <BR> sWait.BeginAccept(proOnAccept,sWait);
<BR> Console.Write(sNew.RemoteEndPoint.ToString());
<BR> // 超过最大连接数 <BR> if(nSocketNum >=
MAX_CONNECT) <BR> { <BR> sNew.Close();
<BR> return ; <BR> } <BR>
<BR> <BR> for(int i =0; i<
MAX_CONNECT ; i++) <BR> { <BR>
<BR> if(aSock[i].thisSocket == null)
<BR> { <BR> aSock[i].thisSocket = sNew; //insert
<BR> WaitForData(i); <BR> nSocketNum ++;
<BR> Console.WriteLine(" insert a Socket
,position = {0},count = {1}",i,nSocketNum);
<BR> break; <BR> } <BR> <BR>
} <BR> <BR> <BR> <BR>
} <BR> catch(ObjectDisposedException) <BR> {
<BR> System.Diagnostics.Debugger.Log(0,"1","\n OnClientConnection:
Socket has been closed\n"); <BR> }
<BR> catch(SocketException se) <BR> {
<BR> Console.WriteLine ( se.Message );
<BR> } <BR> <BR> // <BR> }
<BR> <BR> /// <summary> <BR> ///
处理连接错误,断开连接,释放资源 <BR> /// </summary>
<BR> /// <param name="se"></param>
<BR> /// <param name="nIndex"></param>
<BR> private void ProcessSocketException(SocketException
se,int nIndex) <BR> { <BR> if(se
!= null) <BR> Console.WriteLine ("Error code
= {0},message = '{1}'",se.ErrorCode,se.Message
); <BR> <BR> //断开连接 <BR>
if(aSock[nIndex].thisSocket != null) <BR> {
<BR> aSock[nIndex].Reset(); <BR> if( nSocketNum
> 0) <BR> nSocketNum --; <BR>
Console.WriteLine("remove a Client Socket ,position=
{0},count = {1}",nIndex,nSocketNum); <BR> }
<BR> } <BR> <BR> <A
href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10508028>10 楼</A>gujianxin(木头象)<INPUT class=user5 title="五级用户 该版得分小于等于5000分,大于2000分" type=button></STRONG><SPAN>回复于
2003-03-28 11:36:22 得分 0 </SPAN></H3>
<P>/////////////// <BR> //好多垃圾 <BR> <BR>
<BR> /// <summary> <BR> /// 活动检测
<BR> /// </summary> <BR> private
void ActiveCheck() <BR> { <BR>
<BR> for(int i =0, j= 0; (i<
MAX_CONNECT) &&( j < nSocketNum);
i++) <BR> { <BR> if(aSock[i].thisSocket ==
null) <BR> continue; <BR> try <BR>
{ <BR> if(aSock[i].thisSocket.Connected ) <BR>
aSock[i].thisSocket.Send(bCheck); <BR> else <BR>
ProcessSocketException(null,i); <BR> } <BR>
catch(Exception ) <BR> { <BR>
ProcessSocketException(null,i); <BR> } <BR>
<BR> j ++; <BR> } <BR> <BR> }
<BR> <BR> <BR> <BR> }
<BR> } <BR> <A
href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10508414>11 楼</A>whxbb(whxbb)<INPUT class=user4 title="四级用户 该版得分小于等于2000分,大于1000分" type=button></STRONG><SPAN>回复于
2003-03-28 11:44:38 得分 0 </SPAN></H3>
<P>使用 threadpool 管理线程。<A
href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10520222>12 楼</A>citymeteor(流星)<INPUT class=user5 title="五级用户 该版得分小于等于5000分,大于2000分" type=button></STRONG><SPAN>回复于
2003-03-28 16:27:12 得分 0 </SPAN></H3>
<P>threadpool 怎么用?<A
href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10521134>13 楼</A>wolve(祝你生活愉快)<INPUT class=star1 title="一星用户 该版得分小于等于10000分,大于5000分" type=button></STRONG><SPAN>回复于
2003-03-28 16:47:38 得分 0 </SPAN></H3>
<P>我最近也在写这个东西,我的思路是用同步。 <BR>
服务开始时启动一个主线程,如果有客户端连接时就产生一个线程处理与客户端的连接。我把线程和客户端封装在类ClientThread中,另处还有一个类Protocol处理数据传输,我是根据java中的思路来做的,不过效率好像很低,有兴趣交流一下<A
href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10529987>14 楼</A>SaSBYa(人的价值就是为社会创造的价值。)<INPUT class=star1 title="一星用户 该版得分小于等于10000分,大于5000分" type=button></STRONG><SPAN>回复于
2003-03-28 21:54:02 得分 0 </SPAN></H3>
<P>关注<A href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10534384>15 楼</A>qiuafa()<INPUT class=user2 title="二级用户 该版得分小于等于500分,大于100分" type=button></STRONG><SPAN>回复于
2003-03-29 09:13:18 得分 0 </SPAN></H3>
<P>接分&捧场<A
href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10538492>16 楼</A>gweidian(向高手学习)<INPUT class=user3 title="三级用户 该版得分小于等于1000分,大于500分" type=button></STRONG><SPAN>回复于
2003-03-29 11:59:20 得分 0 </SPAN></H3>
<P>UP<A href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10551849>17 楼</A>Lostinet(每晚 8:00 见)<INPUT class=star2 title="二星用户 该版得分小于等于30000分,大于10000分" type=button></STRONG><SPAN>回复于
2003-03-29 23:06:20 得分 0 </SPAN></H3>
<P>谁帮 <BR>
http://expert.csdn.net/Expert/TopicView1.asp?id=1567017<A
href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10553961>18 楼</A>ji0(际零)<INPUT class=user1 title="一级用户 该版得分小于等于100分" type=button></STRONG><SPAN>回复于
2003-03-30 07:15:14 得分 0 </SPAN></H3>
<P>up<A href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10563560>19 楼</A>huan_jinwu(金屋藏娇,得抱源码归)<INPUT class=user5 title="五级用户 该版得分小于等于5000分,大于2000分" type=button></STRONG><SPAN>回复于
2003-03-30 18:25:43 得分 0 </SPAN></H3>
<P>学习ing<A href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10613014>20 楼</A>turui()<INPUT class=user2 title="二级用户 该版得分小于等于500分,大于100分" type=button></STRONG><SPAN>回复于
2003-04-01 14:08:53 得分 <EM>20</EM></SPAN></H3>
<P>服务程序应该尽量少的开辟线程,通讯用异步来完成。 <BR>
服务程序应该尽量少的,开辟释放内存,事先开辟好足够的内存自己做内存管理(可以参看unix的内存管理) <BR>
服务程序尽量少的减少io操作,例如文件的读取,可以采用内存映像文件。 <BR> <BR>
服务程序与客户端通讯的协议要定义清楚规范,尽量少的减少数据的传递 <BR>
还有一些常用的方法,例如:解析xml的时候不要用XmlDocument,数据量大的时候非常慢,改用XmlReader,自己控制。<A
href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10613098>21 楼</A>turui()<INPUT class=user2 title="二级用户 该版得分小于等于500分,大于100分" type=button></STRONG><SPAN>回复于
2003-04-01 14:10:49 得分 0 </SPAN></H3>
<P>数据查找用:hush table 排序用:快速排序等,常用的方法。 <BR>
还有一些,像数据缓冲,连接管理,等有功夫自己好好研究。<A
href="http://topic.csdn.net/t/20030327/22/1586528.html#">Top</A></P>
<H3><STRONG><A class=anchor name=r_10762579>22 楼</A>zkp(zkp)<INPUT class=user1 title="一级用户 该版得分小于等于100分" type=button></STRONG><SPAN>回复于
2003-04-06 23:06:05 得分 0 </SPAN></H3>
<P>发现问题主要出现在服务端传送大量的数据(数据库结果),导致内存暴涨,超出最大内存,服务down掉。 <BR>
而客户端主要是因为超时或网络问题出现无法连接的错误。 <BR> 目前解决方案如下: <BR>
在服务端采用分批传送的方法,能够使服务器内存有所降低,也使客户端响应速度大大加快。 <BR>
并且使用传输完成标示,如果客户端没有收到完成标示,就一直尝试读取,直到超时。 <BR>
为了能应付大规模访问,服务端采用Http的请求响应方式,一旦请求完成就自动断开。 <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -