问题描述
局域网客户端连接服务器,我想用for循环遍历连接服务器,例如服务器IP:192.168.1.10,如果从192.168.1.1开始连接,一直执行到正确的IP。但是一个错误的ip要花上20s,如此将会花大量的时间。如何缩短连接时间。以下代码usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Linq;usingSystem.Text;usingSystem.Windows.Forms;usingSystem.Net.Sockets;usingSystem.Net;usingSystem.Threading;usingSystem.Collections;namespace客户端{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}voidShowMsg(stringstr){txtLog.AppendText(str+"rn");list.Add(str);}privatevoidForm1_Load(objectsender,EventArgse){Control.CheckForIllegalCrossThreadCalls=false;}SocketsocketSend;privatevoidbutton1_Click(objectsender,EventArgse){if(txtNum.Text.Length==12&&txtName.Text.Length>=2){try{MessageBox.Show("登录成功");socketSend=newSocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);ThreadSocket();//Threadth=newThread(Socket);//th.IsBackground=true;//th.Start();}catch{}}elseif(txtNum.Text.Length!=12){MessageBox.Show("学号格式有误,请从新输入");txtNum.Clear();txtName.Clear();}else{MessageBox.Show("姓名格式有误,请从新输入");txtNum.Clear();txtName.Clear();}}voidThreadSocket(){stringhostname=Dns.GetHostName();//得到本机名IPHostEntrylocalhost=Dns.GetHostByName(hostname);//得到IPv4的地址IPAddresslocaladdr=localhost.AddressList[0];string[]ips=localaddr.ToString().Split('.');a=Convert.ToInt32(ips[0]);b=Convert.ToInt32(ips[1]);c=Convert.ToInt32(ips[2]);//Threadth=newThread(Socket);//th.IsBackground=false;//th.Start();Socket();}inta;intb;intc;intd=1;IPAddressip;booljudge=false;voidSocket(){try{while(judge==false){ip=IPAddress.Parse(a+"."+b+"."+c+"."+d);IPEndPointpoint=newIPEndPoint(ip,50000);socketSend.Connect(point);judge=true;}ShowMsg(txtNum.Text+txtName.Text+":连接成功");button1.Hide();button2.Visible=true;button3.Visible=true;button4.Visible=true;button5.Visible=true;btnBack.Visible=true;textBox1.Visible=true;txtNum.ReadOnly=true;txtName.ReadOnly=true;}catch{d++;Socket();}}voidShowMsg(stringstr1,stringstr2){txtNum.Text=str1;txtName.Text=str2;button1.Hide();}privatevoidbutton2_Click(objectsender,EventArgse){stringstr=textBox1.Text+"-"+txtName.Text+":正确";调用(str);}privatevoidbutton3_Click(objectsender,EventArgse){stringstr=textBox1.Text+"-"+txtName.Text+":放弃";调用(str);}privatevoidbutton4_Click(objectsender,EventArgse){stringstr=textBox1.Text+"-"+txtName.Text+":错误";调用(str);}intcount=1;void调用(stringstr){if(count<30){count++;textBox1.Text="第"+count+"题";txtLog.AppendText(str+"rn");list.Add(str);}else{txtLog.AppendText(str+"rn");list.Add(str);button2.Hide();button3.Hide();button4.Hide();}}ArrayListlist=newArrayList();intr;privatevoidbtnBack_Click(objectsender,EventArgse){if(count<=1){}elseif(count==30){button2.Visible=true;button3.Visible=true;button4.Visible=true;}else{count--;r=list.Count;list.RemoveAt(r-1);//删除最后一个元素txtLog.Clear();for(inti=0;i<list.Count;i++){txtLog.AppendText(list[i].ToString()+"rn");}}textBox1.Text="第"+count+"题";}privatevoidbutton5_Click(objectsender,EventArgse){list.RemoveAt(0);txtLog.Clear();for(inti=0;i<list.Count;i++){txtLog.AppendText(list[i]+"rn");}byte[]buffer=System.Text.Encoding.UTF8.GetBytes(txtLog.Text);socketSend.Send(buffer);button2.Hide();button3.Hide();button4.Hide();btnBack.Hide();button5.Hide();}}}
程序会卡在代码socketSend.Connect(point);
如何优化代码
解决方案
解决方案二:
遍历这个是没法优化了,但是socket链接返回结果,不可能会20s吧?不能修改返回结果的时间么?
解决方案三:
不要动不动就以“死循环”编程。如果块“死循环”这个想法,可能决策者会“玩死你”。只有那些会按照事件来安排程序代码的人才能精明地设计软件,而一些动不动就写“死循环”代码的人则是各种炮灰级的程序员。你若想成为一个有时间去研究能独当一面能力技术的程序员(而不是死抠一小段代码的“底层”程序员),就从删除你的Socket()方法中的循环语句开始。你的Socket()方法应该是几毫秒就结束了,不应该出现任何循环语句。这样,你就能了解另外一种编程设计思想。
解决方案四:
网络错误要十几秒、20秒才能捕捉到,这也是很正常的事情。编程设计本来就是一种智能活动。例如人家知道几十个任务并发执行,人家也知道“只选前3个最快返回的结果”来判断(而扔掉剩下几十个比较慢的任务)。这个如果没有在学校里学过基础知识(学校学的太少的话),在工作中也是必修的基础知识。如果你没有先发散后集中的编程设计思想,你就会纠结在一堆什么while循环的相互牵制、相互嵌套之中,只能做点简单的顺序操作,不知道如何进行真正发挥电脑、网络的特点的流程设计。整个计算机系统,在你那里只是一个大个的四则计算器,你只会顺序操作用一个手指头“点点点”,不知道如何设计并发的以及网络的软件。
解决方案五:
用Task执行该任务,可以设置超时退出。
解决方案六:
这种想法是不是有点反人类啊,如果IP最后一位是100呢?最好是固定IP,或者固定使用机器名.实在要如此可以开10个线程,取得最先返回结果的那个IP.
解决方案七:
引用5楼tcmakebest的回复:
这种想法是不是有点反人类啊,如果IP最后一位是100呢?最好是固定IP,或者固定使用机器名.实在要如此可以开10个线程,取得最先返回结果的那个IP.
有试过多线程,但是语句button2.Visible=true;button3.Visible=true;button4.Visible=true;button5.Visible=true;btnBack.Visible=true;textBox1.Visible=true;
执行过,但是却没有效果,有点莫名其妙,你看得出是哪里有问题吗
解决方案八:
引用4楼DOwnstairs的回复:
用Task执行该任务,可以设置超时退出。
有比较好的例子的链接吗
解决方案九:
引用7楼hu3625173的回复:
Quote: 引用4楼DOwnstairs的回复:
用Task执行该任务,可以设置超时退出。有比较好的例子的链接吗
C#多线程编程中有好多可以设置超时退出的类。具体看你需要什么样的。https://msdn.microsoft.com/zh-cn/library/给你鱼竿