【发布时间】:2018-05-28 00:13:04
【问题描述】:
我正在尝试让我的代码接受两个或更多客户端到我的服务器程序。这是代码。我需要有关如何同时接受多个客户的代码方面的帮助。我的端口出现错误。它说“每个套接字地址(协议/网络地址/端口)通常只允许使用一次”
命名空间 TCPServer { 公共部分类Form1:表格 {
//Create TCP/IP Socket
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
TcpListener mTCPListener;
TcpClient mTCPClient = new TcpClient();
NetworkStream serverStream;
byte[] mRx;
public Form1()
{
InitializeComponent();
}
void onCompleteAcceptTcpClient(IAsyncResult iar)
{
TcpListener tcpl = (TcpListener)iar.AsyncState;
try
{
ThreadStart delegateR = new ThreadStart(() =>
mTCPClient = tcpl.EndAcceptTcpClient(iar));
Thread R = new Thread(delegateR);
R.Start();
printLine("Client Connected...");
//Begin Asynchronous Read
mRx = new byte[1024];
mTCPClient.GetStream().BeginRead(mRx, 0, mRx.Length, onCompleteReadFromTCPClientStream, mTCPClient);
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnStartListening_Click_1(object sender, EventArgs e)
{
try
{
IPAddress ipaddr;
int nPort = 23000;
#region Validating IP Address
//if (!int.TryParse(tbPort.Text, out nPort))
//{
// nPort = 23000;
//}
if (!IPAddress.TryParse(tbIPAddress.Text, out ipaddr))
{
MessageBox.Show("Invalid IP address supplied.");
return;
}
#endregion
mTCPListener = new TcpListener(ipaddr, nPort);
//Start Listening
mTCPListener.Start();
//ThreadStart delegateT = new ThreadStart(() => { RefreshLot(lotId); });
//Thread T = new Thread(delegateT);
//T.Start();
ThreadStart delegateT = new ThreadStart(() => mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener));
Thread T = new Thread(delegateT);
T.Start();
//Begin accept tcp client (only one)
//mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener));
if (mTCPListener.Pending())
{
nPort = nPort + 1;
mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener);
}
}
catch (Exception ex)
{
throw ex;
}
}
void onCompleteReadFromTCPClientStream(IAsyncResult iar)
{
TcpClient tcpc;
int nCountReadBytes = 0;
string strRecv;
try
{
tcpc = (TcpClient)iar.AsyncState;
nCountReadBytes = tcpc.GetStream().EndRead(iar);
if (nCountReadBytes == 0)
{
MessageBox.Show("Client disconnected.");
return;
}
strRecv = Encoding.ASCII.GetString(mRx, 0, nCountReadBytes);
printLine(strRecv);
mRx = new byte[1024];
tcpc.GetStream().BeginRead(mRx, 0, mRx.Length, onCompleteReadFromTCPClientStream, tcpc);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void printLine(string _strPrint)
{
tbConsoleOutput.Invoke(new Action<string>(doInvoke), _strPrint);
}
public void doInvoke(string _strPrint)
{
tbConsoleOutput.Text = _strPrint + Environment.NewLine + tbConsoleOutput.Text;
}
private void onCompleteWriteToClientStream(IAsyncResult iar)
{
try
{
TcpClient tcpc = (TcpClient)iar.AsyncState;
tcpc.GetStream().EndWrite(iar);
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnSend_Click_1(object sender, EventArgs e)
{
byte[] tx = new byte[1024];
if (string.IsNullOrEmpty(tbPayload.Text)) return;
try
{
if (mTCPClient != null)
{
if (mTCPClient.Client.Connected)
{
//This is the message that will be sent
tx = Encoding.ASCII.GetBytes("Server MESRII sent: " + tbPayload.Text + " " + DateTime.Now);
mTCPClient.GetStream().BeginWrite(tx, 0, tx.Length, onCompleteWriteToClientStream, mTCPClient);
}
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void btnStartListening2_Click(object sender, EventArgs e)
{
}
}
【问题讨论】:
-
我对之前帖子的回答有什么问题:stackoverflow.com/questions/47799387/… 我在第一条评论中说过,您不能有来自相同 IP 地址和相同端口号的两个连接。如果您想从同一个 IP 进行测试,那么您需要两个端口号。因此,创建两个具有两个不同端口号的侦听器。让两个侦听器使用相同的接受事件。测试后,您可以消除第二个听众。客户端在大型网络上尝试多个端口号和多个服务器的连接很常见。
-
如何分配不同的端口号“让我们动态地说”?如果不是两个客户,而是另一个...
-
服务器端口号永远不会动态分配。它们总是预先分配给一个端口号或一系列端口号。在客户端,您要么检查以确保另一个应用程序没有使用与同一服务器相同的端口号,要么尝试在一个端口号上建立连接,如果连接失败,请尝试该范围内的下一个端口号。使用 TCP,您只能有一个具有相同三个参数的连接 1) 源 IP 地址 2) 目标 IP 地址 3) 端口号。