Unity how to find a server from client using NetworkDiscovery - c#

[I work in c#]
In order to decide weather a device should become a server with local client or client alone (for main-server-less networking) I need to find out if there are any other available servers for that device before turning into a server with local client if not for another client device to join by either receiving NetworkDiscovery broadcasts from a server or not - currently I can't get a client to receive broadcast from a server.
I have created two empty gameobjects each with scripts, one script makes it a server and should be broadcasting from its NetworkDiscovery via NetworkDiscovery.StartAsServer() but currently one my client whose NetworkDiscovery has been set to NetworkDiscovery.StartAsClient() is not getting theOnRecievedBroadcast() function called hence not receiving broadcasts from the server.
The two scripts shown below are the client and server:
Client -
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class SearchForServers : MonoBehaviour {
bool serverIsFound;
NetworkDiscovery NetworkDiscovery;
// Use this for initialization
void Start () {
serverIsFound = false;
NetworkClient Client = new NetworkClient();
NetworkDiscovery = gameObject.AddComponent<NetworkDiscovery>();
NetworkDiscovery.Initialize();
NetworkDiscovery.StartAsClient();
}
void OnRecievedBroadcast(string fromAdress, string data)
{
serverIsFound = true;
}
// Update is called once per frame
void Update () {
Debug.Log("Server Found = " + serverIsFound);
}
}
Server -
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class CreateServer : MonoBehaviour
{
bool create;
int minPort = 10000;
int maxPort = 10010;
int defaultPort = 10000;
NetworkDiscovery NetworkDiscovery;
void Start()
{
create = true;
if (create == true)
{
int serverPort = createServer();
if (serverPort != -1)
{
Debug.Log("Server created on port : " + serverPort);
}
else
{
Debug.Log("Failed to create Server");
}
}
NetworkDiscovery = gameObject.AddComponent<NetworkDiscovery>();
NetworkDiscovery.Initialize();
NetworkDiscovery.StartAsServer();
}
//Creates a server then returns the port the server is created with. Returns -1 if server is not created
int createServer()
{
int serverPort = -1;
//Connect to default port
bool serverCreated = NetworkServer.Listen(defaultPort);
if (serverCreated)
{
serverPort = defaultPort;
Debug.Log("Server Created with default port");
}
else
{
Debug.Log("Failed to create with the default port");
//Try to create server with other port from min to max except the default port which we trid already
for (int tempPort = minPort; tempPort <= maxPort; tempPort++)
{
//Skip the default port since we have already tried it
if (tempPort != defaultPort)
{
//Exit loop if successfully create a server
if (NetworkServer.Listen(tempPort))
{
serverPort = tempPort;
break;
}
//If this is the max port and server is not still created, show, failed to create server error
if (tempPort == maxPort)
{
Debug.LogError("Failed to create server");
}
}
}
}
return serverPort;
}
}
These are the console logs with the debug logging
Thanks for reading I hope that you can realise where I have gone wrong or indeed how to complete said task otherwise. #Programmer

First of all you named each server and client script the-same name. You don't need OnRecievedBroadcast in the server code. You only need it in the client code. OnRecievedBroadcast is not being called on the client side because you did not override NetworkDiscovery. You must override it.
Here is a simple Discovering Code:
Client:
public class NetClient : NetworkDiscovery
{
void Start()
{
startClient();
}
public void startClient()
{
Initialize();
StartAsClient();
}
public override void OnReceivedBroadcast(string fromAddress, string data)
{
Debug.Log("Server Found");
}
}
Server:
public class NetServer : NetworkDiscovery
{
// Use this for initialization
void Start()
{
Application.runInBackground = true;
startServer();
}
//Call to create a server
public void startServer()
{
int serverPort = createServer();
if (serverPort != -1)
{
Debug.Log("Server created on port : " + serverPort);
broadcastData = serverPort.ToString();
Initialize();
StartAsServer();
}
else
{
Debug.Log("Failed to create Server");
}
}
int minPort = 10000;
int maxPort = 10010;
int defaultPort = 10000;
//Creates a server then returns the port the server is created with. Returns -1 if server is not created
private int createServer()
{
int serverPort = -1;
//Connect to default port
bool serverCreated = NetworkServer.Listen(defaultPort);
if (serverCreated)
{
serverPort = defaultPort;
Debug.Log("Server Created with deafault port");
}
else
{
Debug.Log("Failed to create with the default port");
//Try to create server with other port from min to max except the default port which we trid already
for (int tempPort = minPort; tempPort <= maxPort; tempPort++)
{
//Skip the default port since we have already tried it
if (tempPort != defaultPort)
{
//Exit loop if successfully create a server
if (NetworkServer.Listen(tempPort))
{
serverPort = tempPort;
break;
}
//If this is the max port and server is not still created, show, failed to create server error
if (tempPort == maxPort)
{
Debug.LogError("Failed to create server");
}
}
}
}
return serverPort;
}
}
The createServer() function is a function from your last question. I don't think you can have both server and client code running at the-same time in the Editor.
For testing, you must build the code in your pc with the server code/NetServer enabled. Run the built program then from your Editor you can run the client/NetClient code. This should discover game on the server.

Related

Start SCS server from another class (WinForms)

I'm trying to implement a SCS framework server with WinForms in C# but I am having issues making it work. The server standalone works fine when using it in the Main method (no WinForms). I have a client-sided and a server-sided sample code from the SCS framework that I'm trying to implement in WinForms together with some of my own code. It all went well until I decided to try and use WinForms aswell (I had to move the server code to a class of it's own).
I am not getting any errors when I am starting the server, however I can't connect with the client anymore (worked before I moved the server to a class of its own). Client gets System.Net.Sockets.SocketException. On the server-side, I get the error System.InvalidOperationException when the client is trying to connect.
This is my Form1.cs:
using System;
using System.Windows.Forms;
namespace Server_Test
{
public partial class Form1 : Form
{
public static Form1 Self;
Server server = new Server();
public Form1()
{
InitializeComponent();
Self = this;
}
public void rtb1Text(string text)
{
richTextBox1.AppendText(text);
}
public void rtb2Text(string text)
{
richTextBox2.Text = text;
}
private void button1_Click(object sender, EventArgs e)
{
if (button1.Text.EndsWith("Start"))
{
button1.Text = "Stop";
server.ServerInit();
}
else if (button1.Text.EndsWith("Stop"))
{
button1.Text = "Start";
// Does nothing atm
}
}
}
}
And this is my Server.cs
using System;
using Hik.Communication.Scs.Communication.EndPoints.Tcp;
using Hik.Communication.Scs.Communication.Messages;
using Hik.Communication.Scs.Server;
namespace Server_Test
{
class Server
{
public void ServerInit()
{
// Create a server that listens 10085 TCP port for incoming connections
var server = ScsServerFactory.CreateServer(new ScsTcpEndPoint(10085));
// Register events of the server to be informed about clients
server.ClientConnected += Server_ClientConnected;
server.ClientDisconnected += Server_ClientDisconnected;
// Start the server
server.Start();
// Form1.Self.rtb1Text("Server has been started successfully.\n");
Console.WriteLine("Server has been started successfully.\n");
}
static void Server_ClientConnected(object sender, ServerClientEventArgs e)
{
Form1.Self.rtb1Text("A new client with ID: " + e.Client.ClientId + " has connected.\n");
// Register to MessageReceived event to receive messages from new client
e.Client.MessageReceived += Client_MessageReceived;
}
static void Server_ClientDisconnected(object sender, ServerClientEventArgs e)
{
Form1.Self.rtb1Text("A client is disconnected! Client Id = " + e.Client.ClientId + "\n");
}
static async void Client_MessageReceived(object sender, MessageEventArgs e)
{
var message = e.Message as ScsTextMessage; // Server only accepts text messages
if (message == null)
{
return;
}
//Get a reference to the client
var client = (IScsServerClient)sender;
Form1.Self.rtb1Text("Client (ID:" + client.ClientId + ") sent a request: " + message.Text + "\n");
switch (message.Text)
{
case "api":
HttpPost httpPost = new HttpPost();
var apiResponse = await httpPost.SendPost("robot_info");
//Send reply message to the client
client.SendMessage(
new ScsTextMessage(
apiResponse,
message.MessageId //Set first message's id as replied message id
));
break;
default:
break;
}
}
}
}
My guess is that I'm doing something wrong when creating a new instance of the Server class and how I'm initializing/starting the server. Might be something else though, I've tried debugging but it didn't make me any smarter.
Any ideas?

Extreme UDP-Package-Loss in HoloLens2 -UWP-Application

In my HoloLens2 application sometimes the UDP-Package-receive rate drops instantly from 40 packages per second to 0-2 packages per second and stays there (size of packages between 2000 byte and 60000 byte. The application is made with Unity3d and .Net Sockets for networking. This behaviour sometimes happens straight from application startup, sometimes after 30 minutes, so basically quiet random. Even Restarting HoloLens2 doesn´t help in such a situation. The application logs no exception or error messages. On my Unity-Editor the Application can handle the network traffic without any problem.
It feels like some Network buffer got stuffend and drops all packages so did I miss some Cleanup command in my Networking-Code or is there another way to face Receive-Overload in my code?
Or is HoloLens2 somehow limited in it´s Bandwith when running via Ethernet (and not Wifi)?
At the same time my application also maintains a peer-to-peer Video-stream (WebRTC with MixedReality Capture). This stream works well over the whole lifetime of the application flawlessly.
using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using UnityEngine;
public class UdpCommunicationDotNet : ICommunicator
{
#region Fields
private int m_PackageCountPerSecond;
private int m_PackageCountTotal;
private Thread m_PackageCounterResetRoutine;
private Socket m_SenderSocket;
private Socket m_ReceiverSocket;
private IPEndPoint m_ServerIpEndPoint;
private IPEndPoint m_ReceiverIpEndPoint;
private IPEndPoint m_ListenerIpEndPoint;
private EndPoint m_ServerEndPoint;
private EndPoint m_ReceiverEndPoint;
private byte[] m_ReceiveBuffer;
private IDataProvider m_DataProvider;
private int m_MaxBufferByteLength;
private bool m_ReceiveEnabled = true;
public IDataProvider DataProvider { get => m_DataProvider; set => m_DataProvider = value; }
#endregion
#region Constructor
public UdpCommunicationDotNet()
{
m_MaxBufferByteLength = GameManager.Instance.GetConfigurationManager.RuntimeConfig.NetworkSettings.MaxBufferByteLength;
}
#endregion
#region Public Methods
public void Initialize(DataLineConfig dataLineConfig)
{
m_ReceiveBuffer = new byte[m_MaxBufferByteLength];
m_ServerIpEndPoint = dataLineConfig.serverEndPoint;
m_ReceiverIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
m_ServerEndPoint = (EndPoint)m_ServerIpEndPoint;
m_ReceiverEndPoint = (EndPoint)m_ReceiverIpEndPoint;
m_ListenerIpEndPoint = dataLineConfig.receiverEndPoint;
}
public void StartReceiver()
{
if (InitializeReceiverSocket())
{
m_ReceiveEnabled = true;
StartReceiving();
}
}
public void EndReceiver()
{
m_ReceiveEnabled = false;
}
public void StartSender()
{
InitializeSenderSocket();
}
public void Send(Byte[] data)
{
try
{
//added this, remove it
//Debug.Log("SentMyDataPackage");
m_SenderSocket.BeginSendTo(data, 0, data.Length, SocketFlags.None, m_ServerEndPoint, new AsyncCallback(OnSendCallback), null);
}
catch (Exception e)
{
Debug.LogError("Failed to send udp data through the UdpCommunicator: " + e.Message);
}
}
#endregion
#region Private Methods
private bool InitializeReceiverSocket()
{
bool isInitialized = false;
try
{
m_ReceiverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
m_ReceiverSocket.Bind(m_ListenerIpEndPoint);
isInitialized = true;
}
catch (Exception e)
{
Debug.LogError("Failed to initialize the receiver socket in the UdpCommunicator: " + e.Message);
}
return isInitialized;
}
private void InitializeSenderSocket()
{
m_SenderSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
}
private void StartReceiving()
{
m_ReceiverSocket.BeginReceiveFrom(m_ReceiveBuffer, 0, m_ReceiveBuffer.Length, SocketFlags.None, ref m_ReceiverEndPoint, new AsyncCallback(OnReceiveCallback), m_ReceiverEndPoint);
}
private void DistributeData(object dataObject)
{
byte[] data = (byte[])dataObject;
m_DataProvider.DistributeData(data);
}
#endregion
#region Callback Methods
private void OnSendCallback(IAsyncResult asyncResult)
{
try
{
m_SenderSocket.EndSend(asyncResult);
}
catch (Exception e)
{
Debug.LogError("Failed to close the opened send connection in the UdpCommunicator: " + e.Message);
}
}
private void OnReceiveCallback(IAsyncResult asyncResult)
{
try
{
if (DebugManager.Instance.isActive)
{
DebugManager.Instance.m_PackageCounter.UpdateMainCountTotal(m_PackageCountTotal);
}
int receivedBufferSize = m_ReceiverSocket.EndReceiveFrom(asyncResult, ref m_ReceiverEndPoint);
Array.Resize(ref m_ReceiveBuffer, receivedBufferSize);
byte[] copiedBuffer = new byte[receivedBufferSize];
Buffer.BlockCopy(m_ReceiveBuffer, 0, copiedBuffer, 0, receivedBufferSize);
Thread thread = new Thread(DistributeData);
thread.SetApartmentState(ApartmentState.STA);
thread.Start(copiedBuffer);
m_ReceiveBuffer = new byte[m_MaxBufferByteLength];
}
catch (Exception e)
{
Debug.LogError("Failed to fetch the received data in the UdpCommunicator: " + e.Message);
}
finally
{
if (m_ReceiveEnabled)
{
StartReceiving();
}
else
{
m_ReceiverSocket.Shutdown(SocketShutdown.Both);
m_SenderSocket.Shutdown(SocketShutdown.Both);
m_ReceiverSocket.Close();
m_SenderSocket.Close();
}
}
}
#endregion
}
Edit:
By writing the Minimal Reproducable Example I found out the reason for the missbehaviour! I realized that if I send more than 4 Packages in one chunk (so send package1, send package2, send package3, send package4, etc, wait x ms, start again) HoloLens2 is starting to drop my udp packages.
In contrast, when I send Package1-> wait for 4 ms -> send package2 -> wait for 4 ms -> send package 3 -> wait 4ms and so on and after sending all different packages simply restart sending, it Works like a charm!
Also, when I send the packages via EthernetOverUSB (what is not a usable approach for my case), even if I send all packages in one chunk it works.
For me this behaviour is wiered and I can´t explain it to myself. Maybe somebody of you can ? Anyways, thanks for anybody who tried to help me!

Unity3d - Node.js tcp connection, Client did not update immediately

I am testing node.js as TCP server and Unity3d as client for my up coming project.
I create a simple chat interface with unity3d that can send and receive data from the server. Everything seems to work fine until I test with 2 clients, one in Unity editor and another with Unity application, whenever I send the message, the server immediately pickup and display in terminal. But the client side only update the display interface when I click to focus on the client, be it Unity editor or the Unity application itself.
Below are my codes:
Node.js
net = require('net');
var clients = [];
net.createServer(function (socket) {
socket.name = socket.remoteAddress + ":" + socket.remotePort
clients.push(socket);
socket.write("Welcome " + socket.name + "\n");
broadcast(socket.name + " joined the chat\n", socket);
socket.on('data', function (data) {
broadcast(socket.name + "> " + data, socket);
});
socket.on('end', function () {
clients.splice(clients.indexOf(socket), 1);
broadcast(socket.name + " left the chat.\n");
});
function broadcast(message, sender) {
clients.forEach(function (client) {
if (client === sender) return;
client.write(message);
});
process.stdout.write(message)
}
}).listen(5000);
// Put a friendly message on the terminal of the server.
console.log("Chat server running at port 5000\n");
client.cs
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Net.Sockets;
using System.IO;
public class client : MonoBehaviour {
private bool socketReady;
private TcpClient socket;
private NetworkStream stream;
private StreamWriter writer;
private StreamReader reader;
public Text servermessage;
public InputField input;
// Use this for initialization
void Start () {
ConnectToServer ();
}
// Update is called once per frame
void Update () {
if(socketReady){
if(stream.DataAvailable){
string data = reader.ReadLine ();
if(data != null){
OnIncomingData (data);
}
}
}
}
public void ConnectToServer(){
if(socketReady)
return;
string host = "127.0.0.1";
int port = 5000;
try
{
socket = new TcpClient(host,port);
stream = socket.GetStream();
writer = new StreamWriter(stream);
reader = new StreamReader(stream);
socketReady = true;
Debug.Log("socket :"+ reader.ToString());
}
catch (System.Exception e)
{
Debug.Log("socket error :"+ e);
}
}
private void OnIncomingData(string data){
Debug.Log ("server : "+ data);
servermessage.text = data;
}
public void OnOutgoingData(string data){
if (!socketReady)
return;
if (input.text == "") {
writer.WriteLine (data);
} else {
writer.WriteLine (input.text);
}
writer.Flush ();
input.text = "";
}
}
What is missing? How can I make it that I can see the immediate update on all my client interface?
This is not caused by your code, but due to the Unity editor. By default the unity editor does not run applications in the background.
You can turn run-in-background on inEdit > Project Settings > Settings-Player
There should be a field Run in background. Turn it on, and it should update even when you are not focused
See Also Run In background

connect to other computer that is not local

I try to connect from my pc to other pc what I have at home and both are connected to the internet. So I check the other pc with the program MyIpAdress and it is like: 38.xx.xx.xx.
And I have this program:The server:
public delegate void StatusChangedHandler(object sender, StatusChangedEventArgs e);
public class StatusChangedEventArgs : EventArgs
{
// This will store our only parameter / event argument, which is the event message
private string EventMsg;
// We need to define this property in order to retrieve the message in the event handler, back in Form1.cs
public string EventMessage
{
get
{
return EventMsg;
}
}
// The constructor will set the message
public StatusChangedEventArgs(string strEventMsg)
{
EventMsg = strEventMsg;
}
}
class Monitor
{
// Will store the IP address passed to it
IPAddress ipAddress;
// The constructor sets the IP address to the one retrieved by the instantiating object
public Monitor(IPAddress address)
{
ipAddress = address;
}
// Declare the event that we'll fire later
public event StatusChangedHandler StatusChangedEvent;
// The thread that will hold the connection listener
private Thread thrListener;
// The TCP object that listens for connections
private TcpListener tlsServer;
// The thread that will send information to the client
private Thread thrSender;
// Will tell the while loop to keep monitoring for connections
bool ServRunning = false;
public void StartMonitoring()
{
// Get the IP of the first network device, however this can prove unreliable on certain configurations
IPAddress ipaLocal = ipAddress;
if (tlsServer == null)
{
// Create the TCP listener object using the IP of the server and the specified port
tlsServer = new TcpListener(ipaLocal, 1986 );
}
// Start the TCP listener and listen for connections
tlsServer.Start();
// The while loop will check for true in this before checking for connections
ServRunning = true;
// Start the new tread that hosts the listener
thrListener = new Thread(KeepListening);
thrListener.Start();
}
private void KeepListening()
{
TcpClient tclServer;
// While the server is running
while (ServRunning == true)
{
// Accept a pending connection
tclServer = tlsServer.AcceptTcpClient();
// Start a new thread where our new client who just connected will be managed
thrSender = new Thread(new ParameterizedThreadStart(AcceptClient));
// The thread calls the AcceptClient() method
thrSender.Start(tclServer);
}
}
// Occures when a new client is accepted
private void AcceptClient(object newClient)
{
// Set the argument/parameter to a message explaining what just happened
StatusChangedEventArgs evArg = new StatusChangedEventArgs("A client was successfully accepted.");
// Fire the event because a new client was accepted
StatusChangedEvent(this, evArg);
}
}
But if I fill in in the textbox the ipadress: 38.xxx.xxx.xx,
I will get this error:
An unhandled exception of type 'System.Net.Sockets.SocketException'
occurred in System.dll
Additional information: The requested address is not valid in its context
So it can only see Local ipAdresses?
But how to change it, that it also finds not local Ipadresses?
And this is the client application:
public partial class Form1 : Form
{
private string UserName = "Unknown";
private StreamWriter swSender;
private StreamReader srReceiver;
private TcpClient tcpServer;
// Needed to update the form with messages from another thread
private delegate void UpdateLogCallback(string strMessage);
// Needed to set the form to a "disconnected" state from another thread
private delegate void CloseConnectionCallback(string strReason);
private Thread thrMessaging;
private IPAddress ipAddr;
private bool Connected;
public Form1()
{
Application.ApplicationExit += new EventHandler(OnApplicationExit);
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
// If we are not currently connected but awaiting to connect
if (Connected == false)
{
// Initialize the connection
InitializeConnection();
}
else // We are connected, thus disconnect
{
CloseConnection("Disconnected at user's request.");
}
}
private void ReceiveMessages()
{
// Receive the response from the server
srReceiver = new StreamReader(tcpServer.GetStream());
// If the first character of the response is 1, connection was successful
string ConResponse = srReceiver.ReadLine();
// If the first character is a 1, connection was successful
if (ConResponse[0] == '1')
{
// Update the form to tell it we are now connected
this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { "Connected Successfully!" });
}
else // If the first character is not a 1 (probably a 0), the connection was unsuccessful
{
string Reason = "Not Connected: ";
// Extract the reason out of the response message. The reason starts at the 3rd character
Reason += ConResponse.Substring(2, ConResponse.Length - 2);
// Update the form with the reason why we couldn't connect
this.Invoke(new CloseConnectionCallback(this.CloseConnection), new object[] { Reason });
// Exit the method
return;
}
// While we are successfully connected, read incoming lines from the server
while (Connected)
{
// Show the messages in the log TextBox
this.Invoke(new UpdateLogCallback(this.UpdateLog), new object[] { srReceiver.ReadLine() });
}
}
private void InitializeConnection()
{
// Parse the IP address from the TextBox into an IPAddress object
ipAddr = IPAddress.Parse(txtServerIP.Text);
// Start a new TCP connections to the chat server
tcpServer = new TcpClient();
tcpServer.Connect(IPAddress.Any, 1986);
// Helps us track whether we're connected or not
Connected = true;
// Prepare the form
UserName = txtUserName.Text;
// Disable and enable the appropriate fields
txtServerIP.Enabled = false;
txtUserName.Enabled = false;
txtMessage.Enabled = true;
btnSend.Enabled = true;
btnConnect.Text = "Disconnect";
// Send the desired username to the server
swSender = new StreamWriter(tcpServer.GetStream());
swSender.WriteLine(txtUserName.Text);
swSender.Flush();
// Start the thread for receiving messages and further communication
thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
thrMessaging.Start();
}
private void UpdateLog(string strMessage)
{
// Append text also scrolls the TextBox to the bottom each time
txtLog.AppendText(strMessage + "\r\n");
}
private void btnSend_Click(object sender, EventArgs e)
{
SendMessage();
}
private void SendMessage()
{
if (txtMessage.Lines.Length >= 1)
{
swSender.WriteLine(txtMessage.Text);
swSender.Flush();
txtMessage.Lines = null;
}
txtMessage.Text = "";
}
// Closes a current connection
private void CloseConnection(string Reason)
{
// Show the reason why the connection is ending
txtLog.AppendText(Reason + "\r\n");
// Enable and disable the appropriate controls on the form
txtServerIP.Enabled = true;
txtUserName.Enabled = true;
txtMessage.Enabled = false;
btnSend.Enabled = false;
btnConnect.Text = "Connect";
// Close the objects
Connected = false;
swSender.Close();
srReceiver.Close();
tcpServer.Close();
}
public void OnApplicationExit(object sender, EventArgs e)
{
if (Connected == true)
{
// Closes the connections, streams, etc.
Connected = false;
swSender.Close();
srReceiver.Close();
tcpServer.Close();
}
}
}
So I changed this line:
tcpServer.Connect(IPAddress.Any, 1986);
but If I run the server application I will get this error:
I get the same error as by the client:
An unhandled exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
Additional information: The requested address is not valid in its context
Thank you
I show you two Images:This is the Server app. That works
This is the Client app, that doesnt work:
And if I change the code in the client app, like this:
tcpServer.Connect(ipAddr, 1986); Then I will get this error:
Additional information: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
But I can pin the other pc
In the client program I have this:
private void InitializeConnection()
{
// Parse the IP address from the TextBox into an IPAddress object
ipAddr = IPAddress.Parse(txtServerIP.Text);
// Start a new TCP connections to the chat server
tcpServer = new TcpClient();
tcpServer.Connect(IPAddress.Any, 1986);
// Helps us track whether we're connected or not
Connected = true;
// Prepare the form
UserName = txtUserName.Text;
// Disable and enable the appropriate fields
txtServerIP.Enabled = false;
txtUserName.Enabled = false;
txtMessage.Enabled = true;
btnSend.Enabled = true;
btnConnect.Text = "Disconnect";
// Send the desired username to the server
swSender = new StreamWriter(tcpServer.GetStream());
swSender.WriteLine(txtUserName.Text);
swSender.Flush();
// Start the thread for receiving messages and further communication
thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
thrMessaging.Start();
}
what I have to change then?
Maybe you have to allow TCP connections on your port in the firewall for the applications on both PCs. Make sure that connections from and to the network are allowed.

Connecting to Server from two different IPs doesn't work (Chat App)

I building a client/server chat app , where the server is listening on IP number 127.0.0.1 and port 1212 , and clients are supposed to connect to that IP & Port .
The problem - in the following order :
I run the server on my computer , listening on (127.0.0.1 & port 1212)
I'm also running a client on my computer (the same computer as #1) that successfully connects to the server (127.0.0.1 & port 1212)
I'm running another client from a different IP , but when trying connect to the server (127.0.0.1 & port 1212) the attempt failed . In this IP , I do not run another server !!!
I don't understand the reason for that ... here is the code :
Server side :
public partial class ServerForm : Form
{
private TcpListener m_tcpServer;
private TcpClient m_tcpClient;
private Thread th;
private ServerNotifier m_chatDialog;
private List<ServerNotifier> m_formArray = new List<ServerNotifier>();
private ArrayList m_threadArray = new ArrayList();
public delegate void ChangedEventHandler(object sender, EventArgs e);
public event ChangedEventHandler m_Changed;
public delegate void SetListBoxItem(String str, String type);
// some code
public void StartListen()
{
IPAddress localAddr = IPAddress.Parse("127.0.0.1");
m_tcpServer = new TcpListener(localAddr, Int32.Parse(tbPortNumber.Text));
m_tcpServer.Start();
// Keep on accepting Client Connection
while (true)
{
// New Client connected, call Event to handle it.
Thread t = new Thread(new ParameterizedThreadStart(NewClient));
m_tcpClient = m_tcpServer.AcceptTcpClient();
t.Start(m_tcpClient);
}
}
}
The winform of the server ....
Client side :
public partial class ClientForm : Form
{
// to know when a button was clicked
private bool m_connectionEstablished = false;
private bool m_enterKeyPressed = false;
private bool m_notRunning = false; // flip this when the server is not running
private NetworkStream m_ns = null;
private StateObject m_state = null;
private TcpClient m_clientTcpConnection = null;
// ip and m_username entered by the client
private String m_ipNumberString = String.Empty;
private String m_username = String.Empty;
private int m_port = 0;
public bool StartTheClient(int m_port)
{
byte[] data = new byte[1024];
string inputFromClient = "";
string portString = "";
try
{
// "127.0.0.1"
this.m_clientTcpConnection = new TcpClient(this.m_ipNumberString , this.m_port);
}
catch (Exception e)
{
// this.rtbClientChat.SelectionColor = Color.LimeGreen;
this.m_notRunning = true; // m_clientTcpConnection is not running
MessageBox.Show("The server is currently not running , try again later!");
// connection failed
return false;
}
this.rtbClientChat.SelectedText = "Connected to the Server...";
String local_IP = ((IPEndPoint)m_clientTcpConnection.Client.LocalEndPoint).Address.ToString();
String local_Port = ((IPEndPoint)m_clientTcpConnection.Client.LocalEndPoint).Port.ToString();
this.rtbClientChat.SelectedText = "\nConnected on IP address " + local_IP + " and Port " + local_Port;
this.rtbClientChat.SelectedText = "\nEnter a message to send to the Server";
this.m_ns = m_clientTcpConnection.GetStream();
this.m_state = new StateObject();
this.m_state.workSocket = m_clientTcpConnection.Client;
this.m_clientTcpConnection.Client.BeginReceive(m_state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(OnReceive), m_state);
// connection established successfully
this.m_connectionEstablished = true;
return true;
}
/// <summary>
/// connet/disconnect
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (this.connectionLabel.Checked == true)
{
// then the user checked the "connet/disconnect" checkbox
// now check if the user also filled the m_port number
try
{
// trying to check if the user entered something is the m_port box
// grab port number
m_port = Int32.Parse(this.boxPortNumber.Text);
m_ipNumberString = this.ipBoxNumber.Text;
// grab IP number
if (m_ipNumberString == string.Empty)
{
MessageBox.Show("Please enter a valid IP Number!");
this.connectionLabel.Checked = false;
return;
}
// grab username
this.m_username = this.usernameBox.Text;
if (this.m_username == string.Empty)
{
MessageBox.Show("Please enter a Username!");
this.connectionLabel.Checked = false;
return;
}
StartTheClient(m_port);
}
catch (Exception exp)
{
if (this.m_notRunning == true)
{
// then the user tried to initiate connection
// while the m_clientTcpConnection is disconnected
this.m_notRunning = false;
}
else
{
// the user didn't put anything in the m_port box
MessageBox.Show("Please enter a Port number !");
this.connectionLabel.Checked = false;
}
}
}
}
Its winform :
Any idea why this is happening ?
Much appreciated !
127.0.0.1 is a localhost. You should specify the IP of the server in the network. You can easily find the IP of the server by running ipconfig in command prompt.
And the listener should also be started on that IP address.
127.0.0.1 In computer networking, localhost means this computer. So if you run your client on another pc, it will try to connect to the server on that pc, but your server is on another. Set the client IP to the one where you have the server.
127.0.0.1
In case if you have more than one network interface on the server you should start your listener like this, for more details follow the link:
m_tcpServer = new TcpListener(IPAddress.Any, Int32.Parse(tbPortNumber.Text));
TcpListener Constructor
Every device has its own localhost (127.0.0.1).
You cannot connect to another PC localhost (127.0.0.1), so your server should have IP such as 192.168.0.1 with specified port which is reachable from another PC.
If not, everytime it will only try to connect to its own localhost!
normally we just use localhost to test our network program internally. but it won't success if you want test externally with localhost.
127.0.0.1 on any machine refers to itself ( localhost) .
So your client code on different machine need to refer to a server IP.
Every machine has two IP's one is internal 127.0.0.1 and other can be external like 192.168.1.10
You need to provide the client code with a external IP address in that LAN

Categories

Resources