I'm trying to make my code accept two or more clients to my server program. Here is the code. I need help with the code on how to accept multiple clients at the same time. I got an error with the port. It says " Only one usage of each socket address (protocol/network address/port) is normally permitted "
namespace TCPServer { public partial class Form1 : Form {
//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)
{
}
}
You should create single TcpListener
on your server, besause only one listener can use one port. When you getting new connection ( AcceptTcpClient
method), you may begin new thread for messaging exchange with client. You can see good examples in this question
I was working in the code and took all the suggestions provided. What I did was Call the Start listening this way...
`private void btnStartListening_Click_1(object sender, EventArgs e) { try { index++;
IPAddress ipaddr = IPAddress.Any;
int x = Convert.ToInt32(tbPort.Text);
int nPort = x;
//#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
if (nPort >= 23000)
{
nPort = nPort + 1;
mTCPListener = new TcpListener(ipaddr, nPort);
//Start Listening on port nPort + 1
mTCPListener.Start();
testingThreadStart.Add(new ThreadStart(() => mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener)));
//ThreadStart delegateT = new ThreadStart(() => mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener));
testingThread.Add(new Thread(testingThreadStart[index]));
//Thread T = new Thread(delegateT);
//T.Start();
testingThread[index].Start();
//Begin accept tcp client (only one)
//mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener));
}
else
{
mTCPListener = new TcpListener(ipaddr, nPort + 1);
//Start Listening on port 23000
mTCPListener.Start();
ThreadStart delegateT = new ThreadStart(() => mTCPListener.BeginAcceptTcpClient(onCompleteAcceptTcpClient, mTCPListener));
Thread T = new Thread(delegateT);
T.Start();
}
}`
Also added list of threads on the beginning of the code...
List<ThreadStart> testingThreadStart = new List<ThreadStart>();
List<Thread> testingThread = new List<Thread>();
and thats how it worked. If anyone need/want the complete code, I can post it. For future examples.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.