一个Socket 两个端口

LIMINLY520 2011-08-11 03:47:36
在C# 控制台中
如何使用一个Socket 监听两个端口
因为业务的需要
所以需要实现这样的功能
网上有的说是开两个监听程序就好了
可是我运行了一下
程序就停在了第一个监听那边了
不往下执行了
各路大虾们
要怎样解决的啊
...全文
528 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
Avoid 2011-08-16
  • 打赏
  • 举报
回复
如果你想写服务端程序,用select对初学者难了点。用多线程服务器模式简单点。

google一搜一大把,我也不贴代码了。
Avoid 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 liminly520 的回复:]

抱歉啊
题目有点问题啊
那Socket怎样监听多个端口的啊
我在网上看了一下
有用select 的
但是没看懂的啊
还有就是开多个线程的
我是在开第一个Socket的时候 就被阻塞掉了
怎样才能开多个的啊
[/Quote]

都叫Socket了。。。

你想一个袜子穿两个脚上?
mjp1234airen4385 2011-08-16
  • 打赏
  • 举报
回复
就是启动一个线程,而这个线程启动的时候需要参数:System.Threading.ParameterizedThreadStart。
也就是创建一个带启动参数的线程,这下应该明白了吧。
data就是ipe,启动的时候把ipe当作启动参数传过去了:newthread.Start(ipe);
ThreadCallBack就是线程要做的工作,你开启线程总的让它做点什么吧,做的工作就在这里了。
那线程又不知道要做的工作放在那个函数里了,你需要明确的告诉它,需要他的做的工作在ThreadCallBack这个函数里了,并且需要一个参数才能开始执行。这个函数叫做回调函数。
这样newthread.Start(ipe);就启动线程了,就相当于调用函数ThreadCallBack,并且传入了参数ipe。


如果说到这样楼主还是不理解的话,我就无语了。
LIMINLY520 2011-08-16
  • 打赏
  • 举报
回复
咋又没人回答了呢
是不是我太笨了啊
LIMINLY520 2011-08-16
  • 打赏
  • 举报
回复
感谢各路好汉的帮助啊
我现在明白该怎样做了啊
谢谢
Kation 2011-08-15
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 liminly520 的回复:]
引用 16 楼 zip_xg 的回复:
C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;

namespace Wodsoft.Net.Sockets
{
public class TCPL……
[/Quote]
这个是个类。。你实例化就能用了
放在你控制台里。。。
看我写得例子。。
chichenzhe 2011-08-15
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 liminly520 的回复:]
可是我在开线程之前有一个阻塞的
所以也就没办法进行下面的动作了啊
你可以帮我看一下我上面发的那个代码吗?
可以告诉我具体是加在哪边的吗?
谢谢
[/Quote]


教你个最简单的方式实现...
既然你不会写非阻塞socket

那么你的主线程就不要去启动socket而是New2条线程出来, 1条线程开启1个socket端口.
这样的话,开的2个线程阻塞与否就不影响你主线程对他们的调度了.
LIMINLY520 2011-08-15
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 zip_xg 的回复:]
C# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;

namespace Wodsoft.Net.Sockets
{
public class TCPListenerClient : I……
[/Quote]
这个不是控制台的程序吧
都没有main 方法
LIMINLY520 2011-08-15
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 sp1234 的回复:]
引用 5 楼 liminly520 的回复:
抱歉啊
题目有点问题啊
那Socket怎样监听多个端口的啊
我在网上看了一下
有用select 的
但是没看懂的啊
还有就是开多个线程的
我是在开第一个Socket的时候 就被阻塞掉了
怎样才能开多个的啊


“开第一个Socket”这个动作本身就应该在线程内执行,而不是之外。

不过不如使用异步方式。
[/Quote]
可是我在开线程之前有一个阻塞的
所以也就没办法进行下面的动作了啊
你可以帮我看一下我上面发的那个代码吗?
可以告诉我具体是加在哪边的吗?
谢谢
LIMINLY520 2011-08-15
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 mjp1234airen4385 的回复:]
引用 20 楼 chichenzhe 的回复:
引用 18 楼 liminly520 的回复:
可是我在开线程之前有一个阻塞的
所以也就没办法进行下面的动作了啊
你可以帮我看一下我上面发的那个代码吗?
可以告诉我具体是加在哪边的吗?
谢谢



教你个最简单的方式实现...
既然你不会写非阻塞socket

那么你的主线程就不要去启动socket而是New2条线程出来, ……
[/Quote]

在这里面的data是哪里来的啊
还有 new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(ThreadCallBack)); 中的ThreadCallBack 是什么?????
mjp1234airen4385 2011-08-15
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 chichenzhe 的回复:]
引用 18 楼 liminly520 的回复:
可是我在开线程之前有一个阻塞的
所以也就没办法进行下面的动作了啊
你可以帮我看一下我上面发的那个代码吗?
可以告诉我具体是加在哪边的吗?
谢谢



教你个最简单的方式实现...
既然你不会写非阻塞socket

那么你的主线程就不要去启动socket而是New2条线程出来, 1条线程开启1个socket端口.
这样的话,开……
[/Quote]

就是这个方法了。
void ThreadCallBack(object data)
{
Socket server; //创建服务器套接字server
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //设置套接字的类型,不必深究,大体知道就可以
IPEndPoint ipe = (IPEndPoint)data; //绑定到端口,推荐设置为1024以后的空闲端口
server.Bind(ipe); //绑定到端口
server.Listen(20); //server套接字实现监听
Console.WriteLine("Wait for the client to build Connection.....");
while (true)
{ //得到包含客户端信息的套接字
Socket client = server.Accept(); //阻塞方法
//新建线程,并将ClientThread类的实例的方法赋给线程
}
}

int port = 6688;
private void button3_Click(object sender, EventArgs e)
{
IPAddress ipadd = IPAddress.Parse("127.0.0.1"); //绑定到我的电脑的IP
IPEndPoint ipe = new IPEndPoint(ipadd, port++); //绑定到端口,推荐设置为1024以后的空闲端口
System.Threading.Thread newthread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(ThreadCallBack));
newthread.Start(ipe);
return;
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 liminly520 的回复:]
抱歉啊
题目有点问题啊
那Socket怎样监听多个端口的啊
我在网上看了一下
有用select 的
但是没看懂的啊
还有就是开多个线程的
我是在开第一个Socket的时候 就被阻塞掉了
怎样才能开多个的啊
[/Quote]

“开第一个Socket”这个动作本身就应该在线程内执行,而不是之外。

不过不如使用异步方式。
Kation 2011-08-13
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;

namespace Wodsoft.Net.Sockets
{
public class TCPListenerClient : IDictionary<string, object>
{
internal TCPListenerClient(TCPListener listener, Socket socket)
{
this.socket = socket;
this.listener = listener;
data = new Dictionary<string, object>();
this["RemoteEndPoint"] = socket.RemoteEndPoint;
}

internal Socket socket;
private TCPListener listener;

public void Send(byte[] data)
{
listener.Send(this, data);
}

#region 字典

private Dictionary<string, object> data;

public void Add(string key, object value)
{
data.Add(key.ToLower(), value);
}

public bool ContainsKey(string key)
{
return data.ContainsKey(key.ToLower());
}

public ICollection<string> Keys
{
get { return data.Keys; }
}

public bool Remove(string key)
{
return data.Remove(key.ToLower());
}

public bool TryGetValue(string key, out object value)
{
return data.TryGetValue(key.ToLower(), out value);
}

public ICollection<object> Values
{
get { return data.Values; }
}

public object this[string key]
{
get
{
if (ContainsKey(key))
return data[key.ToLower()];
return null;
}
set
{
if (ContainsKey(key))
data[key.ToLower()] = null;
else
Add(key, value);
}
}

public void Add(KeyValuePair<string, object> item)
{
data.Add(item.Key.ToLower(), item.Value);
}

public void Clear()
{
data.Clear();
}

public bool Contains(KeyValuePair<string, object> item)
{
return this[item.Key] == item.Value ? true : false;
}

public void CopyTo(KeyValuePair<string, object>[] array, int arrayIndex)
{
data.ToArray().CopyTo(array, arrayIndex);
}

public int Count
{
get { return data.Count; }
}

public bool IsReadOnly
{
get { return false; }
}

public bool Remove(KeyValuePair<string, object> item)
{
if (this[item.Key] != item.Value)
return false;
return Remove(item.Key);
}

public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
{
return data.GetEnumerator();
}

System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return data.GetEnumerator();
}

#endregion
}
}


你只要实例化多个TCPListener,然后把它们的事件都用同一个Method处理即可。

listener = new TCPListener();
listener.Port = 5000;
listener.ListenCount = 65536;
listener.ReceiveBufferSize = 65536;
listener.SendBufferSize += 65536;
listener.AcceptCompleted += Accepted;
listener.DisconnectCompleted += Disconnect;
listener.ReceiveCompleted += Received;
listener.SendCompleted += Sent;
listener.Start();
Kation 2011-08-13
  • 打赏
  • 举报
回复
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;

namespace Wodsoft.Net.Sockets
{
public class TCPListener : IEnumerable<TCPListenerClient>
{
private Socket socket;
private HashSet<TCPListenerClient> clients;

/// <summary>
/// 实例化TCP监听者。
/// </summary>
public TCPListener()
{
ReceiveBufferSize = 65536;
SendBufferSize = 65536;
clients = new HashSet<TCPListenerClient>();
started = false;
}

/// <summary>
/// 接收缓存大小。
/// </summary>
public int ReceiveBufferSize { get; set; }
/// <summary>
/// 发送缓存大小。
/// </summary>
public int SendBufferSize { get; set; }
/// <summary>
/// 监听数量。
/// </summary>
public int ListenCount { get; set; }
private int port;
/// <summary>
/// 监听端口。
/// </summary>
public int Port
{
get { return port; }
set
{
if (value < 0 || value > 65535)
throw new ArgumentOutOfRangeException(port + "不是有效端口。");
port = value;
}
}

private bool started;

/// <summary>
/// 开始服务。
/// </summary>
public void Start()
{
if (started)
throw new InvalidOperationException("已经开始服务。");
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Any, Port));
socket.Listen(ListenCount);
socket.SendBufferSize = SendBufferSize;
socket.ReceiveBufferSize = ReceiveBufferSize;
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
e.Completed += Accepted;
socket.AcceptAsync(e);
started = true;
}

/// <summary>
/// 停止服务。
/// </summary>
public void Stop()
{
if (!started)
throw new InvalidOperationException("没有开始服务。");
foreach (TCPListenerClient client in clients)
Disconnect(client);
socket.Close();
socket = null;
started = false;
}

/// <summary>
/// 接收完成时引发事件。
/// </summary>
public event EventHandler<SocketAsyncEventArgs> ReceiveCompleted;
/// <summary>
/// 接受客户完成时引发事件。
/// </summary>
public event EventHandler<SocketAsyncEventArgs> AcceptCompleted;
/// <summary>
/// 客户断开完成时引发事件。
/// </summary>
public event EventHandler<SocketAsyncEventArgs> DisconnectCompleted;
/// <summary>
/// 发送完成时引发事件。
/// </summary>
public event EventHandler<SocketAsyncEventArgs> SendCompleted;

private void Accepted(object sender, SocketAsyncEventArgs e)
{
TCPListenerClient client = new TCPListenerClient(this, e.AcceptSocket);
clients.Add(client);
e.Completed -= Accepted;
e.Completed += Received;
e.SetBuffer(new byte[ReceiveBufferSize], 0, ReceiveBufferSize);
e.AcceptSocket.ReceiveAsync(e);

SocketAsyncEventArgs ee = new SocketAsyncEventArgs();
ee.Completed += Accepted;
socket.AcceptAsync(ee);

if (AcceptCompleted != null)
{
AcceptCompleted(client, e);
}
}

private void Sent(object sender, SocketAsyncEventArgs e)
{
TCPListenerClient client = clients.SingleOrDefault(c => c.socket == e.AcceptSocket);
if (client == null)
return;
if (SendCompleted != null)
{
SendCompleted(client, e);
}
e.Dispose();
}

private void Received(object sender, SocketAsyncEventArgs e)
{
TCPListenerClient client = clients.SingleOrDefault(c => c.socket == e.AcceptSocket);
if (client == null)
return;
if (e.BytesTransferred == 0)
{
e.AcceptSocket.Close();
clients.Remove(client);
if (DisconnectCompleted != null)
{
DisconnectCompleted(client, e);
}
e.Dispose();
return;
}

SocketAsyncEventArgs s = new SocketAsyncEventArgs();
s.AcceptSocket = client.socket;
s.Completed += Received;
s.SetBuffer(new byte[ReceiveBufferSize], 0, ReceiveBufferSize);
client.socket.ReceiveAsync(s);

if (ReceiveCompleted != null)
{
ReceiveCompleted(client, e);
}
e.Dispose();
}

private void Disconnected(object sender, SocketAsyncEventArgs e)
{
TCPListenerClient client = clients.SingleOrDefault(c => c.socket == e.AcceptSocket);
if (client == null)
return;
e.AcceptSocket.Close();
clients.Remove(client);
if (DisconnectCompleted != null)
{
DisconnectCompleted(client, e);
}
e.Dispose();
}

/// <summary>
/// 发送数据。
/// </summary>
/// <param name="client">客户端。</param>
/// <param name="data">要发送的数据。</param>
public void Send(TCPListenerClient client, byte[] data)
{
if (!started)
throw new InvalidOperationException("没有开始服务。");
if (!client.socket.Connected)
{
client.socket.Close();
clients.Remove(client);
if (DisconnectCompleted != null)
{
DisconnectCompleted(client, null);
}
return;
}

SocketAsyncEventArgs e = new SocketAsyncEventArgs();
e.AcceptSocket = client.socket;
e.SetBuffer(data, 0, data.Length);
e.Completed += Sent;
client.socket.SendAsync(e);
}

/// <summary>
/// 给所有已连接的客户端发送数据。
/// </summary>
/// <param name="data">要发送的数据。</param>
public void Send(byte[] data)
{
if (!started)
throw new InvalidOperationException("没有开始服务。");
foreach (TCPListenerClient client in clients)
{
if (!client.socket.Connected)
{
client.socket.Close();
clients.Remove(client);
if (DisconnectCompleted != null)
{
DisconnectCompleted(client, null);
}
return;
}
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
e.AcceptSocket = client.socket;
e.SetBuffer(data, 0, data.Length);
e.Completed += Sent;
client.socket.SendAsync(e);
}
}

/// <summary>
/// 断开客户端连接。
/// </summary>
/// <param name="client">要断开的客户端。</param>
public void Disconnect(TCPListenerClient client)
{
if (!started)
throw new InvalidOperationException("没有开始服务。");
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
e.AcceptSocket = client.socket;
e.Completed += Disconnected;
client.socket.DisconnectAsync(e);
}

/// <summary>
/// 获取客户端泛型。
/// </summary>
/// <returns></returns>
public IEnumerator<TCPListenerClient> GetEnumerator()
{
return clients.GetEnumerator();
}

/// <summary>
/// 获取客户端泛型。
/// </summary>
/// <returns></returns>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return clients.GetEnumerator();
}
}
}
sheyt2009 2011-08-13
  • 打赏
  • 举报
回复
同意楼上的方案,用多线程来处理就OK了,建议去学习一下completeport
LIMINLY520 2011-08-12
  • 打赏
  • 举报
回复
怎么都没人回答了啊
帮我看一下啊
chichenzhe 2011-08-12
  • 打赏
  • 举报
回复
1个程序也一样啊.

只要端口可以是2个 就没问题.

你多开1个线程去侦听 其他端口不就行了吗.
LIMINLY520 2011-08-11
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 likai757 的回复:]
C# code

System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(SendDesk));
th.Start(desksoc);
void ……
[/Quote]
那你可以帮我看一下下面的代码
要怎么加

class Threadtcpserver
{

public static ArrayList mmm = new ArrayList();
public static ArrayList clientArray = new ArrayList();
private Socket server; //创建服务器套接字server
public Threadtcpserver()
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //设置套接字的类型,不必深究,大体知道就可以
IPAddress ipadd = IPAddress.Parse("127.0.0.1"); //绑定到我的电脑的IP
IPEndPoint ipe = new IPEndPoint(ipadd, 6688); //绑定到端口,推荐设置为1024以后的空闲端口
server.Bind(ipe); //绑定到端口
server.Listen(20); //server套接字实现监听
Console.WriteLine("Wait for the client to build Connection.....");
while (true)
{ //得到包含客户端信息的套接字
Socket client = server.Accept(); //阻塞方法
clientArray.Add(client);
ClientThread newclient = new ClientThread(client); //创建了ClientThread类的实例
Thread newthread = new Thread(new ThreadStart(newclient.ClientServer));
//新建线程,并将ClientThread类的实例的方法赋给线程
newthread.Start(); //启动线程
}
}
}//class Threadtcpserver
class ClientThread
{
public static int connection = 0; // 统计连接到服务器端的客户端数
public Socket server;
int i;
public ClientThread(Socket ClientSocket)
{
this.server = ClientSocket;
}
public void ClientServer()
{
string data = null;

byte[] bytes = new byte[12048]; // 服务器端设置缓冲区
if (server != null)
{

Threadtcpserver.mmm.Add(server.RemoteEndPoint);
connection++; //有新的连接
Console.WriteLine("A new client get connected!" + server.RemoteEndPoint.ToString());


}
Console.WriteLine("There are {0} clients get connections!", connection);
try
{
while ((i = server.Receive(bytes)) != 0) // 当服务器端的缓冲区内接受到的信息不为空时
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(data + DateTime.Now.ToString());
Console.WriteLine("这是客户端发来的信息");
DateIn(server.ToString(), data);
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
server.Send(msg);
// SenddMsg(0, msg);

Console.WriteLine("The sended data:{0}", data);
}

server.Close(); //如果客户端退出了,则连接数减少
connection--;
Console.WriteLine("Client connection declined!", connection);
}
catch
{

server.Close(); //如果客户端退出了,则连接数减少
connection--;
Console.WriteLine("Client connection declined!", connection);
}
}

}//class ClientThread
class Program
{
static void Main(string[] args)
{
Threadtcpserver instance = new Threadtcpserver();
//创建 Threadtcpserver 的实例,同时运行程序
}
}
LIMINLY520 2011-08-11
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 hui_play 的回复:]
开两个线程,就可以了,你说停在第一个监听那,是因为在一个线程里
[/Quote]
[code=C#]
class Threadtcpserver
{

public static ArrayList mmm = new ArrayList();
public static ArrayList clientArray = new ArrayList();
private Socket server; //创建服务器套接字server
public Threadtcpserver()
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //设置套接字的类型,不必深究,大体知道就可以
IPAddress ipadd = IPAddress.Parse("127.0.0.1"); //绑定到我的电脑的IP
IPEndPoint ipe = new IPEndPoint(ipadd, 6688); //绑定到端口,推荐设置为1024以后的空闲端口
server.Bind(ipe); //绑定到端口
server.Listen(20); //server套接字实现监听
Console.WriteLine("Wait for the client to build Connection.....");
while (true)
{ //得到包含客户端信息的套接字
Socket client = server.Accept(); //阻塞方法
clientArray.Add(client);
ClientThread newclient = new ClientThread(client); //创建了ClientThread类的实例
Thread newthread = new Thread(new ThreadStart(newclient.ClientServer));
//新建线程,并将ClientThread类的实例的方法赋给线程
newthread.Start(); //启动线程
}
}
}//class Threadtcpserver
class ClientThread
{
public static int connection = 0; // 统计连接到服务器端的客户端数
public Socket server;
int i;
public ClientThread(Socket ClientSocket)
{
this.server = ClientSocket;
}
public void ClientServer()
{
string data = null;

byte[] bytes = new byte[12048]; // 服务器端设置缓冲区
if (server != null)
{

Threadtcpserver.mmm.Add(server.RemoteEndPoint);
connection++; //有新的连接
Console.WriteLine("A new client get connected!" + server.RemoteEndPoint.ToString());


}
Console.WriteLine("There are {0} clients get connections!", connection);
try
{
while ((i = server.Receive(bytes)) != 0) // 当服务器端的缓冲区内接受到的信息不为空时
{
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
Console.WriteLine(data + DateTime.Now.ToString());
Console.WriteLine("这是客户端发来的信息");
DateIn(server.ToString(), data);
data = data.ToUpper();
byte[] msg = System.Text.Encoding.ASCII.GetBytes(data);
server.Send(msg);
// SenddMsg(0, msg);

Console.WriteLine("The sended data:{0}", data);
}

server.Close(); //如果客户端退出了,则连接数减少
connection--;
Console.WriteLine("Client connection declined!", connection);
}
catch
{

server.Close(); //如果客户端退出了,则连接数减少
connection--;
Console.WriteLine("Client connection declined!", connection);
}
}
class Program
{
static void Main(string[] args)
{
Threadtcpserver instance = new Threadtcpserver();
Threadtcpserverer iii = new Threadtcpserverer();
//创建 Threadtcpserver 的实例,同时运行程序
}
}
[code]
这个要怎样加一个线程的啊
因为我对这方面不熟
可以请你帮我看一下吗?
Kai-Li 2011-08-11
  • 打赏
  • 举报
回复

System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(SendDesk));
th.Start(desksoc);
void SendDesk(object mysoc)
{
try
{
((Socket)mysoc).Send(lb.ToArray());
}
catch { }
}

可以把Socket对象当做参数传到线程里使用。
加载更多回复(8)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧