Previously I had problem to connecting my client and server using DNS Server, because I could not solve the ip,
public static TcpClient client;
private const int _PORT = 100; // same as server port
public static string connectTo = "kamikazehc.ddns.net";
public static IPAddress ipaddress = null;
resolving IP addresses into DNS name:
private static void ConnectToServer()
{
int attempts = 0;
bool IsValidIP = IPAddress.TryParse(connectTo, out ipaddress);
if (IsValidIP == false)
{
ipaddress = Dns.GetHostAddresses(connectTo)[0];
Console.WriteLine(Dns.GetHostAddresses(connectTo)[0]);
}
client = new TcpClient();
while (!_clientSocket.Connected)
{
try
{
attempts++;
Console.WriteLine("Connection attempt " + attempts);
_clientSocket.Connect(ipaddress, _PORT);
Thread.Sleep(100);
}
catch (SocketException)
{
Console.Clear();
}
}
Console.Clear();
Console.WriteLine("Connected");
}
If I put my local Ip 192.168.x.x I connect.
But if I use my fixed IP or dns the client makes endless attempts to connect.
Using DNS or Fixed IP
Using local IP:
I would like to know how to solve this to be able to connect, I imagine I do not need to modify the code, just configure my internet, but I do not know how to configure
Related
So here's the thing, i'm creating a server/client environment for a game where a port forwarded computer acts as a server, and clients send the first UDP message to connect and get the accept message then start sending the in-game UDP messages after successfully connecting.
The problem is, when I use the local IPs say the server using 10.0.0.7 and a client is using 10.0.0.4, everything works just fine:
Client sends connect message.
Server receives it.
Servers sends back accept message.
Client receives it
All further messages reach both ends without any problem.
But when I use the external IP:
Client sends connect message.
Server receives it.
Servers sends back accept message.
Client receives it
Both ends can send messages but the client doesn't receive any more messages.
Wanted to know at the end if the problem is somehow from the code, or from what I think it's really from, router, NAT, firewalls or anything like that.
(Note: Client sends to server's 8888 port, and server sends back through the client's local port, as it should be.)
Below is the client code, written for Unity:
void Start()
{
client = new UdpClient();
client.Connect(IPAddress.Parse("<Global IP>"), 8888);
client.BeginReceive(new AsyncCallback(ReadMessage), client);
}
private void ReadMessage(IAsyncResult result)
{
IPEndPoint ipEndPoint = null;
string message = Encoding.ASCII.GetString(client.EndReceive(result, ref ipEndPoint));
print("Got: " + message);
string[] wholeMessages = message.Split('#');
for (int w = 0; w < wholeMessages.Length - 1; w++)
{
string[] parts = wholeMessages[w].Split('$');
if (!connected && parts.Length == 3 && parts[0] == "accept" && int.TryParse(parts[1], out ID))
{
connected = true;
code = parts[2];
}
}
client.BeginReceive(new AsyncCallback(ReadMessage), client);
}
public void SendUDP(string message)
{
client.Send(Encoding.ASCII.GetBytes(message), message.Length);
}
Ok, after several trials and errors this worked for me...
//Server Code
private static UdpClient udpClient;
static void Main(string[] args)
{
Console.WriteLine("Server initiated...");
udpClient = new UdpClient(8888);
}
private static void ReadMessage()
{
while (true)
{
try
{
IPEndPoint IPEP = null;
string message = Encoding.ASCII.GetString(udpClient.Receive(ref IPEP));
}
}
}
private static void SendUDP(IPEndPoint e,string message)
{
new UdpClient().Send(Encoding.ASCII.GetBytes(message), message.Length, e);
}
//Client Code
private IPAddress ip;
void Start()
{
ip = Dns.GetHostAddresses("HOSTNAME")[0];
client = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
udpThread = new Thread(new ThreadStart(ReadMessage))
{
IsBackground = true
};
udpThread.Start();
}
private void ReadMessage()
{
while (true)
{
try
{
IPEndPoint IPEP = null;
byte[] data = client.Receive(ref IPEP);
string message = Encoding.ASCII.GetString(data);
}
}
}
public void SendUDP(string message)
{
client.Send(Encoding.ASCII.GetBytes(message), message.Length, new IPEndPoint(ip, 8888));
}
I have been experimenting with some code to find other computer's on my network running my app. Firstly I broadcast and listen for those broadcasts. After that I am a little lost on the next step. Once Computer A knows the ip address of Computer B because of the broadcast how do I put Computer B in a state to accept socket connections. Then how does Computer A begin that connection?
Also I have tried doing the broadcasting with Multicast and cannot get that to work. If anyone has extra time could they show that as well.
Starting Listener and Sender:
private static void StartServer()
{
Task.Factory.StartNew(async () =>
{
await StartListeningAsync();
});
}
private static void StartClient()
{
Task.Factory.StartNew(async () =>
{
await StartSendingAsync();
});
}
Those inner methods:
private static async Task StartSendingAsync()
{
try
{
using (UdpClient _broadcaster = new UdpClient())
{
var ipHost = Dns.GetHostEntry("");
var ipAddr = ipHost.AddressList[ipHost.AddressList.Count() - 1];
IPEndPoint ip = new IPEndPoint(IPAddress.Broadcast, PORT);
var ipAddress = Encoding.ASCII.GetBytes(ipAddr.ToString());
for (int x = 0; x < 10; x++)
{
_broadcaster.Send(ipAddress, ipAddress.Count(), ip);
await Task.Delay(TimeSpan.FromSeconds(6));
}
}
}
catch (Exception ex)
{
}
}
private static async Task StartListeningAsync()
{
while (true)
{
using (UdpClient _listener = new UdpClient(PORT))
{
try
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, PORT);
var incoming = await _listener.ReceiveAsync();
NewPing(incoming.Buffer, incoming.RemoteEndPoint);
await Task.Delay(TimeSpan.FromSeconds(10));
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.TimedOut)
{
//Time out that's fine
}
}
}
}
}
What happens when the listener hears a broadcast:
private static void NewPing(byte[] incoming, IPEndPoint rem)
{
Console.WriteLine($"New ping from {rem.ToString()}, attempting to connect!");
//What should happen here now that one of the computer's know the other exists?
//Start some kind of Socket Accepting method?
}
If I understand correctly, you want a machine to send out a UDP broadcast, and then establish a TCP connection between the two?
I'd perform the following steps:
B is listening for UDP broadcasts
A wants a TCP connection with B, so
A starts listening for incoming TCP connections
A sends out a broadcast saying "I'm listening"
B receives the broadcast and attempts to connect to A
I've created two sample console applications, one server, one client:
Server:
using System;
using System.Net;
using System.Net.Sockets;
class Program
{
static void Main(string[] args)
{
TcpListener listener = new TcpListener(new IPEndPoint(IPAddress.Any, 11220));
listener.Start();
listener.AcceptSocketAsync().ContinueWith((t) => HandleClient(t.Result));
Console.WriteLine($"Listening for TCP connections at port 11220...");
using (UdpClient broadcaster = new UdpClient(AddressFamily.InterNetwork))
{
broadcaster.EnableBroadcast = true;
Console.WriteLine("Broadcasting...");
broadcaster.Send(new byte[] { 1, 2, 3 }, 3, new IPEndPoint(IPAddress.Broadcast, 11221));
}
while (Console.ReadKey(true).Key != ConsoleKey.Q)
{
Console.WriteLine("Press 'Q' to quit");
}
}
static void HandleClient(Socket socket)
{
Console.WriteLine($"TCP connection accepted ({socket.RemoteEndPoint})!");
}
}
Client:
using System;
using System.Net;
using System.Net.Sockets;
class Program
{
static void Main(string[] args)
{
using (UdpClient client = new UdpClient(11221, AddressFamily.InterNetwork))
{
Console.WriteLine("Waiting for broadcast...");
client.EnableBroadcast = true;
client.ReceiveAsync().ContinueWith((t) => HandleBroadcast(t.Result)).Wait();
}
Console.WriteLine("Press any key to continue");
Console.ReadKey(true);
}
static void HandleBroadcast(UdpReceiveResult result)
{
Console.WriteLine($"Received broadcast from {result.RemoteEndPoint}, attempting to connect via TCP");
Socket socket = new Socket(result.RemoteEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(new IPEndPoint(result.RemoteEndPoint.Address, 11220));
}
}
First start the client, then the server. The data sent in the broadcast is just dummy data, but you could include some information like the TCP port number the server is listening at.
PS. Remember that this is just a proof of concept.
I am working with C++ application which is windows service and C# server .
With localhost testing everything works great, but with virtualbox system or the same network computers it doesnt work.
I disabled windows firewall and antivirus.
Here is my C# Server most important code:
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = IPAddress.Parse("192.168.1.2");
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 8517);
tcpListener = new TcpListener(localEndPoint);
tcpListener.Start();
tcpListenerThread = new Thread(listenerSocket);
tcpListenerThread.Start();
}
static void listenerSocket()
{
while (true)
{
try
{
Socket client = tcpListener.AcceptSocket();
clientSockets.Add(client);
}
catch (Exception exc)
{
return;
}
}
}
And here is my C++ client most important code(according msdn examples for c++ socket clients):
connectToServer(){
serviceState = DISCONNECTED;
ConnectSocket = INVALID_SOCKET;
sendbuf = "Client Service is ready";
recvbuflen = DEFAULT_BUFLEN;
//----------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR) {
SaveEvent(L"WSAStartup failed");
}
else{
SaveEvent(L"WSAStartup success");
}
// Create a SOCKET for connecting to server
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (ConnectSocket == INVALID_SOCKET) {
SaveEvent(L"Error creating socket for connecting to server");
WSACleanup();
}
else{
SaveEvent(L"Creating socket for connecting to server success");
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr( std::string(serverIP.begin(), serverIP.end()).c_str());
address.sin_port = htons( serverPort );
//----------------------
// Connect to server.
iResult = connect( ConnectSocket, (SOCKADDR*) &address, sizeof(address) );
if ( iResult == SOCKET_ERROR) {
closesocket (ConnectSocket);
serviceState = DISCONNECTED;
SaveEvent(L"Unable to connect to server");
WSACleanup();
}
else{
serviceState = CONNECTED;
SaveEvent(L"Connected to server : " + serverIP );
u_long iMode = 1;
ioctlsocket(ConnectSocket, FIONBIO, &iMode);
}
}
With localhost it works and i have client and server on the same ip but with different ports.
With different ips i got situation when server doesnt 'hear' client.
My log looks like this:
2017-03-31 18:01:30 Settings readed: server IP = 192.168.1.2, server port = 8517-
2017-03-31 18:01:30 WSAStartup success -
2017-03-31 18:01:30 Creating socket for connecting to server success-
2017-03-31 18:01:31 Unable to connect to server-
I would really appreciate any kind oif help i stuck with this almost one week.
I can that add ping to server ip works on client pc
I got into UDP and decided to make a small chat just for practice.
I ran into a problem and I can't figure it out myself.
I created two c# console Programs which are exactly the same (Just Port is different)
I send a UDP broadcast package and then want to receive it on the second console program. What happens tho is that the program I send the broadcast from receives it and the other program doesn't. Same happens at the other way round.
I already switched off my firewall --> doesn't change anything.
I post you the whole code, I hope you guys can help me I would really love to keep going! Thank you so much!
class Program
{
const int PORT = 10101;
private static readonly UdpClient udpclient = new UdpClient(PORT);
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Red;
udpclient.EnableBroadcast = true;
//bool for calling async receiver just once
bool receiving = false;
Console.WriteLine("Chat 2");
//to keep while loop running --> change later
bool keepchatting = true;
#region keepchating loop
while (keepchatting)
{
if (!receiving)
{
startlistening();
}
receiving = true;
newmessage();
}
}
#endregion
//new message --> call sendmessage to broadcast text via UDP
public static void newmessage()
{
string msg;
msg = Console.ReadLine();
byte[] message = Encoding.ASCII.GetBytes(msg);
sendmessage(message);
}
//Broadcast text via UDP
public static void sendmessage(byte[] tosend)
{
UdpClient client = new UdpClient();
client.EnableBroadcast = true;
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("255.255.255.255"), PORT);
client.Send(tosend, tosend.Length, ip);
client.Close();
Console.WriteLine("Sent!");
}
static IAsyncResult ar = null;
//Setup Async Receive Method
public static void startlistening()
{
ar = udpclient.BeginReceive(RecievedMessage, new object());
}
//Message
public static void RecievedMessage(IAsyncResult ar)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Any, PORT);
byte[] bytes = udpclient.EndReceive(ar, ref ip);
string msg = Encoding.ASCII.GetString(bytes);
Console.WriteLine("Received: " + msg);
startlistening();
}
}
I have changed only two parts to your code, on each client set the remote port number of the other client, try this:
On one client:
const int PORT = 10101;
const int PORT_Remote = 10102;
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("255.255.255.255"), PORT_Remote);
On the other client:
const int PORT = 10102;
const int PORT_Remote = 10101;
IPEndPoint ip = new IPEndPoint(IPAddress.Parse("255.255.255.255"), PORT_Remote);
I've wrote an application recently where I was sending socket messages back and forth between two applications on my laptop. I used 127.0.0.1 (default IP address for local host) for the IP address. Could you try that?
i'm trying to make an application which allows the connection between 2 PCs(i planned on making it multi threaded later but lets keep it more simple at the beginning). This could be either used for chatting or sending data to the other pc and he does something to the data and sends it back.
This is my coding so far:
Server:
class Program
{
private static StreamWriter serverStreamWriter;
private static StreamReader serverStreamReader;
private static bool StartServer()
{
//setting up Listener
TcpListener tcpServerListener = new TcpListener(IPAddress.Any, 56765);
tcpServerListener.Start();
Console.WriteLine("Server Started!");
Console.WriteLine("Waiting for Connection...");
Socket serverSocket = tcpServerListener.AcceptSocket();
try
{
if (serverSocket.Connected)
{
Console.WriteLine("Client connected to Server!");
//open network stream on accepted socket
NetworkStream serverSockStream = new NetworkStream(serverSocket);
serverStreamWriter = new StreamWriter(serverSockStream);
serverStreamReader = new StreamReader(serverSockStream);
}
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
return false;
}
return true;
}
static bool once = false;
static void Main(string[] args)
{
//Set Console Window Stuff
Console.Title = "Server";
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Green;
Console.BufferWidth = 120;
Console.Clear();
//Start Server
if (!StartServer())
Console.WriteLine("Error while Starting Server!");
//Waiting till Client sends Something
while (true)
{
string data = "Append Something to Me - ";
if (!once)//that check -.-
{
serverStreamWriter.WriteLine(data);
serverStreamWriter.Flush();
once = true;
}
Console.WriteLine("Client: " + serverStreamReader.ReadLine());
if (serverStreamReader.ReadLine() != data)
{
serverStreamWriter.WriteLine(data);
serverStreamWriter.Flush();
}
}
}
}
Client:
class Program
{
private static StreamReader clientStreamReader;
private static StreamWriter clientStreamWriter;
private static bool ConnectToServer()
{
try
{
TcpClient tcpClient = new TcpClient("127.0.0.1", 56765);
Console.WriteLine("Connected to Server!");
NetworkStream clientSockStream = tcpClient.GetStream();
clientStreamReader = new StreamReader(clientSockStream);
clientStreamWriter = new StreamWriter(clientSockStream);
}
catch (Exception e)
{
Console.WriteLine(e.StackTrace);
return false;
}
return true;
}
private static void SendToServer(string message)
{
try
{
clientStreamWriter.WriteLine(message);
clientStreamWriter.Flush();
}
catch (Exception se)
{
Console.WriteLine(se.StackTrace);
}
}
static void Main(string[] args)
{
//Set Console Window Stuff
Console.Title = "Client";
Console.BackgroundColor = ConsoleColor.Black;
Console.ForegroundColor = ConsoleColor.Red;
Console.BufferWidth = 120;
Console.Clear();
if (!ConnectToServer())
Console.WriteLine("Error while Connecting to Server!");
SendToServer("Send Me Data...");
//Waiting till Server sends Something
while (true)
{
string response = clientStreamReader.ReadLine();
Console.WriteLine(response + "|| Appending Text...");
response += "Appended Text!";
Console.WriteLine("Sended " + response + " back to server!");
SendToServer(response);
}
}
}
Even though this isn't really good coding, it works for me, BUT the main problem with this is it only works on my local machine. How would i make it so if i run the server app on my pc and my friend runs the client app on his pc those two connect!? Help would be really great since i wasn't able to found a detailed tutorial or such and i only created this Account to ask for help here :)
TcpClient tcpClient = new TcpClient("localhost", 3333);
Instead of "localhost", use the remote machine's address here.
Edit:
You don't seem to understand how this connection process works, so I'll try to explain it a little better.
Your server is opening up a socket on port 3333, listening for any connections. This process does not need any external IP adress.
You clients are trying to connect to the server. They need to know what server they're connecting to, so you need to supply them with an IP address. An example would be something like
TcpClient tcpClient = new TcpClient("127.0.0.1", 3333);
//this is identical to using "localhost"
There's no way for you to get around at some point using a remote address in the connection protocol. You can't just tell the client "connect on port 3333" and expect it to know exactly where it needs to connect.
The comment explaining how to resolve a local IP address isn't useful in your case, because what you ended up doing was just telling the client to connect to itself, as you resolved the client's IP address and tried to connect to that.
However, you can have multiple clients connect to the same server. In this case you won't need multiple remote IP addresses, you just tell all the clients to connect to the same remote address and then handle that on the server. This is where the RemoteEndPoint comes into effect.
At the server level you can use the RemoteEndPoint to find the IP address of the clients connecting to it, and use this IP address to return information to those clients.
All in all, you WILL have to use some hardcoded address for your initial
TcpClient tcpClient = new TcpClient(address, 3333);
step. There's no way around this.