问题描述
各位大神,现在我做的一个winform控制系统,从测试客户端发送数据到服务器端,为什么只是第一次能够接收到数据后面就没反应了,这个问题苦恼了我很久,请帮我看一下,服务器端界面设计和代码如下所示,测试客户端是一个测试工具。usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;usingSystem.IO;usingSystem.Text.RegularExpressions;usingSystem.Net.Sockets;usingSystem.Net;usingSystem.Threading;namespace路灯控制系统{publicpartialclassForm1:Form{ThreadthreadWatch=null;//负责监听客户端连接请求SocketsocketWatch=null;Dictionary<string,Socket>dictSocket=newDictionary<string,Socket>();Dictionary<string,Thread>dictThread=newDictionary<string,Thread>();publicForm1(){InitializeComponent();TextBox.CheckForIllegalCrossThreadCalls=false;//可以跨线程调用}//16进制字符串转字节数组privatestaticbyte[]strToToHexByte(stringhexString){hexString=hexString.Replace("","");if((hexString.Length%2)!=0)hexString+="";byte[]returnBytes=newbyte[hexString.Length/2];for(inti=0;i<returnBytes.Length;i++)returnBytes[i]=Convert.ToByte(hexString.Substring(i*2,2),16);returnreturnBytes;}///<summary>///字节数组转16进制字符串///</summary>///<paramname="bytes"></param>///<returns></returns>publicstaticstringbyteToHexStr(byte[]bytes){stringreturnStr="";if(bytes!=null){for(inti=0;i<bytes.Length;i++){returnStr+=bytes[i].ToString("X2");}}returnreturnStr;}privatevoidbtnBeginListen_Click(objectsender,EventArgse){//首先创建负责监听的套接字socketWatch=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);//创建本地IP对象IPAddressip=IPAddress.Parse(txtIP.Text.Trim());//创建包含服务器本地监听端口的EndPointIPEndPointendPoint=newIPEndPoint(ip,Convert.ToInt32(txtPort.Text.Trim()));try{//绑定要监听的服务器端口socketWatch.Bind(endPoint);}catch(Exceptionex){MessageBox.Show(ex.ToString());return;}socketWatch.Listen(100);threadWatch=newThread(WatchConnecting);threadWatch.IsBackground=true;threadWatch.Start();ShowMsg("服务器启动成功!");}///<summary>///监控客户端传来的信息///</summary>privatevoidWatchConnecting(){//应用循环不间断地监控客户端传来的连接请求while(true){//开始监听客户端请求,accept会阻断当前线程,要注意SocketsocketConnection=socketWatch.Accept();//一旦监听到客户端的连接请求,就新生成一个客户端相关的套接字//向客户端连接列表控件listbbox中添加建立连接的客户端lbOnline.Items.Add(socketConnection.RemoteEndPoint.ToString());//将成功连接的套接字添加进列表中去dictSocket.Add(socketConnection.RemoteEndPoint.ToString(),socketConnection);ShowMsg("客户端连接成功!");Threadth=newThread(ReceiveMsg);th.IsBackground=true;th.Start(socketConnection);dictThread.Add(socketConnection.RemoteEndPoint.ToString(),th);}}///<summary>///在文本框显示提示信息///</summary>///<paramname="str"></param>privatevoidShowMsg(stringstr){txtMsg.AppendText(str+"rn");}///<summary>///接收连接客户端传过来的数据///</summary>///<paramname="socketConnection">客户端套接字</param>privatevoidReceiveMsg(objectsocketConnection){SocketsocketClient=(Socket)socketConnection;while(true){//定义一个2M的缓存区,将接收的数据存入其中byte[]arrMsgRec=newbyte[2*1024*1024];intlength=-1;try{length=socketClient.Receive(arrMsgRec);//接收客户端传过来的数据并且返回数据长度}catch(SocketExceptionex){ShowMsg("客户端连接异常:"+ex.ToString());dictSocket.Remove(socketClient.RemoteEndPoint.ToString());dictThread.Remove(socketClient.RemoteEndPoint.ToString());lbOnline.Items.Remove(socketClient.RemoteEndPoint.ToString());//MessageBox.Show(ex.ToString());break;}if(length>0){stringstr="接收信息如下:"+byteToHexStr(arrMsgRec).Substring(0,length*2);ShowMsg(str);}socketClient.Close();}}///<summary>///发送消息///</summary>///<paramname="sender"></param>///<paramname="e"></param>privatevoidbtnSend_Click(objectsender,EventArgse){stringstrMsg=txtMsgSend.Text.Trim();byte[]arrSendMsg=strToToHexByte(strMsg);//将要发送的字符串转换成16进制字节数组;stringstrKey="";strKey=lbOnline.Text.Trim();if(string.IsNullOrEmpty(strKey))//判断是不是选择了发送的对象;{MessageBox.Show("请选择你要发送的好友!!!");}else{dictSocket[strKey].Send(arrSendMsg);//解决了sokConnection是局部变量,不能再本函数中引用的问题;ShowMsg("发送信息:"+strMsg);txtMsgSend.Clear();}}}}
解决方案
解决方案二:
socketClient.Close();关了干嘛
解决方案三:
引用楼主zz801028的回复:
各位大神,现在我做的一个winform控制系统,从测试客户端发送数据到服务器端,为什么只是第一次能够接收到数据后面就没反应了,这个问题苦恼了我很久,请帮我看一下,服务器端界面设计和代码如下所示,测试客户端是一个测试工具。
你先Receive,然后Close,不就是这两步吗?!
解决方案四:
编程序是雕虫小技,我们就看看一个人能不能画出流程图就行了。如果不会画流程图,那么他贴的代码也就是不知道从哪里抄来的,而他需要学习的东西,其实是流程图。
解决方案五:
引用1楼u010868852的回复:
socketClient.Close();关了干嘛
最开始是没有关的,不过也只能接受一次。
解决方案六:
引用2楼sp1234的回复:
Quote: 引用楼主zz801028的回复:
各位大神,现在我做的一个winform控制系统,从测试客户端发送数据到服务器端,为什么只是第一次能够接收到数据后面就没反应了,这个问题苦恼了我很久,请帮我看一下,服务器端界面设计和代码如下所示,测试客户端是一个测试工具。你先Receive,然后Close,不就是这两步吗?!
化繁为简,简单滴说就是这两步。关键是我不知道到底哪儿出了问题,第一次以后的接受信息调试一点反应都没有。出错不可怕,知道错误在哪就好说,现在才接触socket编程,可能对你们来说很简单的问题我看不出来。我把另外一位兄弟说的socketClient.Close();之前也删掉测试过,一样的。
解决方案七:
总之接收是在Receive这一步进行的,你收不到就意味着流程没有走到这里既然你懂调试,就应该看程序跑到哪一步了,为什么跑不到Receive
解决方案八:
一样的问题才解决了SocketsocketConnection=socketWatch.Accept();//一旦监听到客户端的连接请求,就新生成一个客户端相关的套接字但是Accept()是堵塞的,就算你不循环他他也是在没有接受到服务端的请求的时候一直堵塞在那里,接受到了请求,就回创建(返回)一个socket的实例为什么会出现只有第一次接受到数据是因为你返回那个socket没有关闭在什么时候关闭在你第一次得到用户请求然后处理好了数据然后这次的事情已经做完了以后在关闭(close)socket注意是最后才关闭socket