I am trying to create a blockchain example where all clients work as a server and a client at once. I have a thread which constantly listens for incoming connections and when a client is accepted, it creates a thread which reads the incoming data and sends data aswell. It works one way, for example if just one server is started and I join to it as a client, but for example I want to start 3 instances and start a server on all 3 of them, and then I want to connect to instance 2 from instance 1 and so on... This is the code for acceping clients and the join, host function:
TcpClient Join()
{
int server_port = int.Parse(port.Text);
klient = new TcpClient();
try
{
klient.Connect("localhost", server_port);
if (klient.Connected) //Če se poveže
{
Console.WriteLine("Connected to server.");
myNetworkStream = klient.GetStream();
}
}
catch (Exception e)
{
}
return klient;
}
TcpListener Host()
{
int port = FreeTcpPort();
IPAddress ip_address = IPAddress.Parse("127.0.0.1"); //parsing ipja
TcpListener host = new TcpListener(ip_address, port);//ustvari listener
label1.Text = port.ToString();
try
{
host.Start();//zagon strežnika
Console.WriteLine("Server started...");
mine_button.Enabled = true;
Sprejemaj_cliente = new Thread(Cakaj_na_clienta);
Sprejemaj_cliente.Start(host);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return host;
}
public void Cakaj_na_clienta(object argument)
{
TcpListener host = (TcpListener)argument;
try
{
while (true) //ČAKANJE NA POŠILJATELJA
{
Console.WriteLine("Waiting for client...");
TcpClient client = host.AcceptTcpClient();
klient = client;
MessageBox.Show("Client connected");
string odjemalec_IP = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString();
int odjemalec_PORT = ((IPEndPoint)client.Client.RemoteEndPoint).Port;
Console.WriteLine("Povezal se je pošiljatelj na naslovu " + odjemalec_IP + ":" + odjemalec_PORT); //Zagon strežnika
myNetworkStream = klient.GetStream();
sync_thread = new Thread(Synchronize);
sync_thread.Start();
send_chain = new Thread(Send_Chain);
send_chain.Start();
}
}
catch (SocketException e)
{
}
}
Related
I tried switching code to following async calls for Server.
I still am getting same issue. First client connects and interacts fine.
The Second client get stuck with SocketException 10060 (Timeout)
Despite switching over to Async calls, second client is still timing out
Any hints or suggestions are welcomed.
Server code
Console.WriteLine("Initialized Server Data");
Console.WriteLine("Starting Server......");
tcpListener = new TcpListener(IPAddress.Any, Port);
tcpListener.Start();
Console.WriteLine($"Server Started on Port: {Port}.");
tcpListener.BeginAcceptTcpClient(ConnectionCallback, null);
ConnectionCallback
TcpClient _client = tcpListener.EndAcceptTcpClient(_result);
//add client to server list
int i = 0;
for (i = 1; i <= MaxPlayers; i++)
{
if (Clients[i].tcp.socket == null)
{
//found empty client slot on server add client
Clients[i].Connect(_client, this);
i = MaxPlayers * 2;
}
}
if (i < MaxPlayers + 2)
{
Program.WriteConsoleLine($"{_client.Client.RemoteEndPoint} failed to connect: Server is full.", ConsoleColor.Red, ConsoleColor.Black);
}
tcpListener.BeginAcceptTcpClient(ConnectionCallback, null);
Clients[i].Connect(...)
public void Connect(TcpClient _socket, Server _actveServer)
{
ActiveServer = _actveServer;
socket = _socket;
socket.ReceiveBufferSize = dataBufferSize;
socket.SendBufferSize = dataBufferSize;
netStream = socket.GetStream();
ReceivedData = new Packet();
receiveBuffer = new byte[dataBufferSize];
Program.WriteConsoleLine($"{_socket.Client.RemoteEndPoint} connect success!!", ConsoleColor.Cyan, ConsoleColor.Black);
Program.WriteConsoleLine($"Sending IntialWelcome as a hello to {_socket.Client.RemoteEndPoint}", ConsoleColor.DarkCyan, ConsoleColor.Black);
ActiveServer.Packer.Send_InitialWelcome(id);
netStream.BeginRead(receiveBuffer, 0, dataBufferSize, ReceiveDataCallback, null);
}
ReceiveDataCallback
private void ReceiveDataCallback(IAsyncResult _result)
{
try
{
int _byteLen = netStream.EndRead(_result);
if (_byteLen <= 0)
{
ActiveServer.Clients[id].Disconnect();
return;
}
byte[] _data = new byte[_byteLen];
Array.Copy(receiveBuffer, _data, _byteLen);
ReceivedData.Reset(HandleData(_data));
}
catch (Exception _err)
{
Program.WriteConsoleLine($"Error receiving TCP data: {_err}", ConsoleColor.Red, ConsoleColor.Black);
ActiveServer.Clients[id].Disconnect();
}
netStream.BeginRead(receiveBuffer, 0, dataBufferSize, ReceiveDataCallback, null);
}
Send Packet function and callback
public void SendPacket(Packet _packet)
{
try
{
if(socket != null)
{
netStream.BeginWrite(_packet.ToArray(), 0, _packet.Length(), EndPackagingData, netStream);
}
}
catch(Exception err)
{
Program.WriteConsoleLine($"Error sending data to Player {id}, via TCP: {err}", ConsoleColor.Red, ConsoleColor.Black);
}
}
private void EndPackagingData(IAsyncResult _result)
{
netStream.EndWrite(_result);
}
I'm using C# for programming a network application. I'm using a thread to listen an IPEndPoint and answer it.
And another socket to send requests which is using in button handlers. I'm using the TCP protocol.
I've done it many times but today when I was testing it after a long time I understand my application can't connect well.
When I use telnet I can connect to my socket or when I create a test socket I can connect it by my application. There is no strange exception or error and I forward ports by Mono.Nat but problem is not ports because it can communicate with server or client side of itself.
Here is my listening socket code:
public static async void HandleIncomingConnection()
{
await ConfigConnection();
Socket Incomingsockresponde = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint LocalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), StandardPorts[0]);
string NetworkCommandString;
byte[] BytedNetworkString = new byte[1024];
byte[] BytedNetworkFile = new byte[1024 * 100000];
int Len, checker = 0, check = 0;
while(true)
{
try
{
check++;
Incomingsockresponde.Bind(LocalEndPoint);
Incomingsockresponde.Listen(1);
Incomingsockresponde = Incomingsockresponde.Accept();
MessageBox.Show("debug:\n Some remote host connected:" + Incomingsockresponde.RemoteEndPoint.ToString());
MessageBox.Show("Host flagged . . .", "Yeap!");
var mainp = new mainprivate();
mainp.Hstate = "Host not flagged";
try
{
//todo:log stuff
Len = Incomingsockresponde.Receive(BytedNetworkString);
NetworkCommandString = Encoding.ASCII.GetString(BytedNetworkString, 0, Len);
RespondeCommand(NetworkCommandString, Incomingsockresponde);
Incomingsockresponde.Disconnect(true);
}
catch (Exception err)
{
checker++;
MessageBox.Show("Something went wrong with this error:\n" + err.ToString(), "Woops!");
if (checker == 3)
{
MessageBox.Show("Host has some issues for connections", "Woops!");
var main2p = new mainprivate();
main2p.Hstate = "Host has some issues on connections";
return;
}
}
}
catch(Exception err)
{
MessageBox.Show("Something went wrong with this error:\n" + err.ToString(), "Woops!");
if(check == 3)
{
MessageBox.Show("Host not flagged . . .", "Woops!");
var main2p = new mainprivate();
main2p.Hstate = "Host not flagged";
return;
}
if(Incomingsockresponde.Connected == true)
Incomingsockresponde.Disconnect(true);
}
}
}
#endregion
[STAThread]
static void Main()
{
//debug:
MessageBox.Show("Here we go ports :\n" + "ResPort: " + ResPort + "-- - StreamPort:" + StreamPort + "-- - EmerPort:" + EmerPort);
Thread HandleIncomingConnectionThread = new Thread(new ThreadStart(HandleIncomingConnection));
HandleIncomingConnectionThread.Start();
connections[0] = "test";
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new welcome());
}
And this is my request code below:
try
{
Program.availsock.Connect(IPAddress.Parse(haddr[0]), Convert.ToInt16(haddr[1]));
}
catch (Exception err)
{
MessageBox.Show("Can't reach the host" + valstr);
//return;
Program.hostsn--;
addacchost(myKeys[i], valstr, new Size(944, 217), "Uavailable remote host");
goto endsock;
}
//connected
byte[] tmpmssg = new byte[1024];
tmpmssg = Encoding.ASCII.GetBytes(Program.hey);
Program.availsock.Send(tmpmssg);
int tmplng = Program.availsock.Receive(tmpmssg);
string rcdval = Encoding.ASCII.GetString(tmpmssg, 0, tmplng);
haddr = null;
Program.availsock.Close(0);
haddr = rcdval.Split('%');
if (!Program.supporteddistros.Contains(haddr[0]) || !Program.supportedversions.Contains(haddr[1]) || !Program.supportedtypes.Contains(haddr[2]))
{
MessageBox.Show("Unsupported remote host" + valstr);
//delete that from there
Program.oridndic.RemoveAt(checker - 1);
Program.hostsn--;
addacchost(myKeys[i], valstr, new Size(944, 217), "Unsupported remote host");
//acchost.Loadlbl = "Unsupported/Deleted";
//hosts2.Controls.Add(acchost);
//return;
goto endsock;
}
I check ports by netstat -ab and it was listening but it just received connections by telnet or my test socket not request side of my code or reverse my request side just sent request to my test socket.
Is this about my code structure?
Am I making a mistake?
Edit: I also defined a inbound rule for all ports and other stuff for windows firewall.
I'm so confused I never faced this situation I'm just looking for a clue.
Ok well that was just a wrong convert for port i did :
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("0.0.0.0"), Convert.toInt16( port int here));
and it should be :
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("0.0.0.0"), int.Parse(Port int here));
Thanks peoples dont help :/
Im implementing a WebService with TCP. The webservice is the Server side that accept multiple clients. Is there any suggestions on how to configure a default port where to start the tcp clients? And with every client connected (aprox. 10 clients) will have an assigned port.
(I'm using Visual Studio 2010 the language is c#, Here is a code block for accepting the clients.)
Any suggestions will be accepted. Thanks!
private void StartListening(object sender, EventArgs e)
{
try
{
//Will move one the array of threads
index++;
//Will get the current IP Address
IPAddress ipaddr = IPAddress.Any;
//Port where the data will pass.
//First Port in use. 10,000
int Port = 10000;
if (true)
{
_TCPListener = new TcpListener(ipaddr, Port);
Port = Port + 1;
//Start Listening
_TCPListener.Start();
ThreadStart.Add(new ThreadStart(() => _TCPListener.BeginAcceptTcpClient(CompleteAcceptClient, _TCPListener)));
Thread.Add(new Thread(ThreadStart[index]));
Thread[index].Start();
}
else
{
_TCPListener = new TcpListener(ipaddr, Port + 2);
_TCPListener.Start();
ThreadStart delegateT = new ThreadStart(() => _TCPListener.BeginAcceptTcpClient(CompleteAcceptClient, _TCPListener));
Thread T = new Thread(delegateT);
T.Start();
}
}
catch(Exception ex)
{
throw ex;
}
}
//Here is the accept client method.
private void CompleteAcceptClient(IAsyncResult iar)
{
TcpListener tcpl = (TcpListener)iar.AsyncState;
try
{
ThreadStart delegateR = new ThreadStart(() => _TCPClient = tcpl.EndAcceptTcpClient(iar));
Thread R = new Thread(delegateR);
R.Start();
mRx = new byte[1024];
_TCPClient.GetStream().BeginRead(mRx, 0, mRx.Length, onCompleteReadFromTCPClientStream, _TCPClient);
}
catch(Exception e)
{
throw e;
}
}
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.
I am starting on Android and in my first application I need to establish a communication between and android table a PC. The communication is direct by staqtic IPs as I need that when I have several PCs and tablets each table only communicates with its PC.
The communication from the tablet to the Pc is already working but from the PC to the table I cannot get data transfered
Android side
public class Server implements Runnable
{
#Override
public void run()
{
while (always==true)
{
while(start2==false)
{
}
try
{
InetAddress serverAddr = InetAddress.getByName("192.168.173.133");
updatetrack("\nServer: Start connecting\n");
//*DatagramSocket socket = new DatagramSocket(SERVERPORT2, serverAddr);/
DatagramSocket socket = new DatagramSocket(SERVERPORT2);
byte[] buf = new byte[17];
DatagramPacket packet = new DatagramPacket(buf, buf.length, serverAddr, SERVERPORT2);
//*DatagramPacket packet = new DatagramPacket(buf, buf.length);/
updatetrack("Server: Receiving\n");
socket.receive(packet);
updatetrack("Server: Message received: '" + new String(packet.getData()) + "'\n");
updatetrack("Server: Succeed!\n");
start2=false;
}
catch (Exception e)
{
updatetrack("Server: Error!\n");
start2=false;
}
}
}
}
192.168.173.133 is the table IP and SERVERPORT2 is 4445
When I start the application it remains waiting for data after displaying "Server: Receiving" but
C# code
public static void Main()
{
IPEndPoint iep2 = new IPEndPoint(IPAddress.Parse("192.168.173.133"), 4445);
string hostname = Dns.GetHostName();
byte[] data = Encoding.ASCII.GetBytes(hostname);
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
sock.SendTo(data, iep2);
sock.Close();
}
I suppose that it is any silly think I am forgotten but after reading many forums and books I am stopped on this point
Any advise will be welcome
You use UDP connection and socket.receive(packet) doesn't wait for packet. If there isn't packet in the buffer this operation throw exception.
Try to change your code to:
#Override
public void run()
{
while (always==true)
{
while(start2==false)
{
}
try
{
InetAddress serverAddr = InetAddress.getByName("192.168.173.133");
updatetrack("\nServer: Start connecting\n");
//*DatagramSocket socket = new DatagramSocket(SERVERPORT2, serverAddr);/
DatagramSocket socket = new DatagramSocket(SERVERPORT2);
while (always==true)
{
try{
byte[] buf = new byte[17];
DatagramPacket packet = new DatagramPacket(buf, buf.length, serverAddr, SERVERPORT2);
//*DatagramPacket packet = new DatagramPacket(buf, buf.length);/
updatetrack("Server: Receiving\n");
socket.receive(packet);
updatetrack("Server: Message received: '" + new String(packet.getData()) + "'\n");
updatetrack("Server: Succeed!\n");
start2=false;
}
catch(Exception ex) {ex.printStackTrace();}
}
}
catch (Exception e)
{
updatetrack("Server: Error!\n");
start2=false;
}
}
}