如何用SOCKET监听多个端口
我目前在一个项目中需要监听两个端口;我以前只用过SOCKET监听一个端口,所以我的想法很简单,就是新建两个线程,每个线程新建一个服务端,绑定一个端口,这样就可以监听两个端口了,代码如下 :private void button1_Click(object sender, EventArgs e)
{
socketOneThread = new Thread(new ThreadStart(StartService1));
socketOneThread.Start();
//加延时5s
Thread.Sleep(2000);
socketTwoThread = new Thread(new ThreadStart(StartService2));
socketTwoThread.Start();
}
public void StartService1()
{
try
{
//Create the listening socket
this._mainSocketOne = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipLocal = new IPEndPoint(IPAddress.Parse("192.168.1.166"), 4001);
//Bind to local IP Address
this._mainSocketOne.Bind(ipLocal);
//Start Listening
this._mainSocketOne.Listen(10);
//Create the call back for any client connecting...
this._mainSocketOne.BeginAccept(new AsyncCallback(OnClientConnectOne), null);
//if (workerSocketOne.Connect)
{
MessageBox.Show("CONNECTING OK!!!");
}
MessageBox.Show("_mainSocketOne.BeginAccept");
}
catch(SocketException se)
{
MessageBox.Show(se.ToString()+"server1");
}
}
public void StartService2()
{
try
{
//Create the listening socket
this._mainSocketTwo = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint ipLocal2 = new IPEndPoint(IPAddress.Parse("192.168.1.166"), 4002);
//Bind to local IP Address
this._mainSocketTwo.Bind(ipLocal2);
//Start Listening
this._mainSocketTwo.Listen(10);
//Create the call back for any client connecting...
this._mainSocketTwo.BeginAccept(new AsyncCallback(OnClientConnectTwo), null);
// MessageBox.Show("_mainSocketTwo.BeginAccept");
}
catch (SocketException se)
{
MessageBox.Show(se.ToString() + "server2");
}
}
目前这样弄好像是可以,但我心里没有底,各位大虾,在一个程序里是不是可以新建多个服务端啊,你们监听多个端口的时候是怎么解决的,我想要一个简单又可靠的方法。谢谢啊,一定给分。 --------------------编程问答-------------------- 这个是可以的吧,可以监听多个端口的,不过假如多个端口传输量大的话,很容易假死状态。
比如,你在服务器上可以上网80端口,可以上QQ:8000端口,可以上3389端口,可以开启21端口,可以TELENT等 --------------------编程问答-------------------- 楼上的,你做过这样的程序没有啊,如果能找到做过这种程序的人核实一下就好了,从原理上来看,也应该是可以。 --------------------编程问答-------------------- 要是谁能够贴一些多端口监听的代码就更好了,因为毕竟这种情况也是经常要遇到的啊, --------------------编程问答-------------------- 还有一个问题,如何让通过线程中新建的SOCKET,发送一些指令出去啊。因为Accetp()中的SOCKET,都是通过线程新建的,那我如何使用这些用线程新建的SOCKET啊。 --------------------编程问答-------------------- 两个端口
是同一个业务服务还是不同的业务服务?
如果是不同的业务服务,可以分为多个进程处理
当然
底层通信类仍然可以使用同一个类
如果是同一个业务服务
确实可以开多个Socket然后绑定多个端口
但我认为没必要开多个端口
--------------------编程问答-------------------- 楼上的,我的两个端口分别接收不同设备发过来的数据。
如何分多个进程啊,我上面的程序代码就是分多线程写的啊,如果不开多个Socket然后绑定多个端口,那要怎么做呢,能给一点代码吗,或者说,我上面的代码如何改啊,在线等。 --------------------编程问答-------------------- 要是每个客户端数据量都很大,开辟多个端口,对每个具体的客户端设置制定的端口,在服务器些处理端口号的程序,使用线程通信。但如果是每个客户端数据量不是很大的话可以考虑设计通信协议,通过通信协议处理事物。 --------------------编程问答-------------------- 楼上说的我不是很明白啊,是不是当每个客户端数据量都很大的时候,开辟多个SOCKET服务端,每个服务端作为一个线程来监听指定的端口啊, --------------------编程问答-------------------- + $exception {"通常每个套接字地址(协议/网络地址/端口)只允许使用一次。"} System.Exception {System.Net.Sockets.SocketException}
--------------------编程问答-------------------- 不知如何解决 --------------------编程问答-------------------- 如何解决,我现在也在做这样的一个服务, --------------------编程问答-------------------- 我也遇到了同样的问题,顶贴,期待大牛回复 --------------------编程问答--------------------
你有新的连接创建的Socket可以放入全局的集合里。到时候就去集合里找就行了。 --------------------编程问答-------------------- 楼主是如何解决的呢 ,我现在也遇到这个问题了 呜呜... --------------------编程问答-------------------- 绑定多个端口与一个端口感觉没有任何好处啊。 --------------------编程问答-------------------- 多个端口,完全没有问题啊,我就经常在项目上这么干。每个监听端口单独在一个线程中运行, 一般情况下 互不影响。 --------------------编程问答-------------------- 大侠 可不可以贴出来点代码,怎么样才能监听多个端口 --------------------编程问答-------------------- 多线程是可以的,但是如果情况是我不清楚事件发生在哪个端口,而需要对几乎所有的端口进行相应怎么做?
想来osi模型中更低的一层,所有的包都是由一个端口进来的,可以用事件的端口模型来侦听所有端口。
Index=WSAWaitForMultipleEvents(EventTotal,Event,FALSE,30,FALSE);
switch (Index)
{
case WSA_WAIT_EVENT_0:
{
WSAEnumNetworkEvents(Socket[Index],Event[Index],&NetworkEvents);
if (NetworkEvents.lNetworkEvents&FD_READ)
{
switch (Index)
{
case 0: //第0个端口
case 1: //第一个端口
。。。。。
}
}
这样当每个端口有事件时程序会自动响应
但觉得还是比较麻烦 --------------------编程问答-------------------- 这个问题同样碰到了,求解啊 --------------------编程问答-------------------- 建议使用一个服务端,根据传输内容区别发送者的身份和处理传输的内容
如01是客房 02是餐厅 03是保安 04是总经理室 --------------------编程问答-------------------- 两个监听端口该怎么写?碰到这问题,自己搞了两三天了,都没有思路,没人带真的搞不了,求大哥们指点一下 --------------------编程问答-------------------- 嘿嘿 学习学习 多个端口 用 异步 ??? --------------------编程问答-------------------- 难道不是多new几个socket然后listen的节奏? --------------------编程问答-------------------- LZ的写法是可以实现的,只不过你写在一起的话后面的操作就比较难区分了,不过原理就是这个原理,开两个线程,分别监听两个端口。 --------------------编程问答-------------------- 想问下对于socket 如何起多个server然后再server间切换? --------------------编程问答-------------------- 开两个端口不用写两个线程,一个就够了! 我写过类似的,开启 8500 跟 8900 两个端口 --------------------编程问答-------------------- 这样写是没问题的,只是你这边完全没必要用线程去开启监听,直接在UI线程里面开启监听就可以了。
--------------------编程问答-------------------- 同问,我在服务端建立了一个全局的socket ; public static Socket Listener_Socket; 用来监听多个端口,比如我循环下面方法开启了多个监听端口:代码如下:,当多个客户端跟服务端进行socket链接的时候,不同端口之间的客户端会相互影响,造成占用通道的情况,进入了假死状态。举个例子如:两个客户端都链接了800端口,这两个客户端就可以进行通讯。若此时,另外两个客户端链接了801端口,按理来说,链接801端口的两个客户端也可以进行通讯,而且跟800的两个正在通讯的客户端互不影响,确实这样吗?不以为然,结果是,首次链接的客户端进入800端口,他们可以进行通讯没错,但是当某一个客户端进入别的端口,如801或者其他都行,就会造成首次链接的客户端(链接800端口的客户端)通信出现障碍,是不是假死我也是猜测的,我在怀疑是不是一个socket只能建立一个监听端口? 而我如今是一个socket监听了多个端口,所有不行吗? 原因不得而知啊?
/// <summary>
/// 启动端口
/// </summary>
/// <param name="Port">端口</param>
/// <returns></returns>
public string StartServerOn(int Port)
{
try
{
IPAddress[] AddressAr = null;
String ServerHostName = "";
try
{
ServerHostName = Dns.GetHostName();
IPHostEntry ipEntry = Dns.GetHostByName(ServerHostName);
AddressAr = ipEntry.AddressList;
}
catch (Exception) { }
if (AddressAr == null || AddressAr.Length < 1)
{
return "无法获取本地地址…错误";
}
Listener_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
Listener_Socket.Bind(new IPEndPoint(AddressAr[0], Port));
Listener_Socket.Listen(-1);
Listener_Socket.BeginAccept(new AsyncCallback(EndAccept), Listener_Socket);
return ("启动监听" + AddressAr[0].ToString() + ":" + Port + "成功!");
}
catch (Exception ex) { return ex.Message; }
} --------------------编程问答-------------------- 如果有用到10个端口,你就写10个类似
thisListener.Bind(thisIpEndPoint);
就行了。似乎也没有什么可说的了。
--------------------编程问答-------------------- 服务器绑定IP,通常应该是 IPAddress.Any。写成 192.168.1.166 只能处理一小部分网络适配服务功能,你根本没有监听服务器上所有适配器。
既然你写了 BeginAccept(异步处理),那么你根本没有必要搞什么“线程”。你可以写,例如:
private void button1_Click(object sender, EventArgs e)这就行了。不需要画蛇添足地弄两个 Thread 在这里过渡一下。
{
......
this.Listener1.Bind(point1);
this.Listener1.BeginAccept(ReceiveProcess, null);
.....
this.Listener2.Bind(point2);
this.Listener2.BeginAccept(ReceiveProcess, null);
}
另外如果两个处理方法不同,你应该先抽象出处理方法的共同部分,例如
然后初始化时写
public abstract class ProcBase
{
public void Process(object o)
{
.....
}
abstract Proc(...);
}
public class Proc1: ProcBase
{
override Proc(...)
{
.....
}
}
public class Proc1: ProcBase
{
override Proc(...)
{
.....
}
}
private void button1_Click(object sender, EventArgs e)
{
......
this.Listener1.Bind(point1);
var p1 = new Proc1();
this.Listener1.BeginAccept(p1.Process, null);
.....
this.Listener2.Bind(point2);
var p2 = new Proc2();
this.Listener2.BeginAccept(p2.Process, null);
}
这样,在ProcBase中写明共通的部分,而子类仅仅写几行不一样的扩展部分。而不要过度地copy代码! --------------------编程问答-------------------- 后边 public class Proc1: ProcBase 改为 public class Proc2: ProcBase
编写服务器程序,不要写任何阻塞的代码,尤其不要写什么 MessageBox.Show 之类的代码。 --------------------编程问答-------------------- 学习学习。。
补充:.NET技术 , C#