I have Thrift client-server application C# client and Python server. All in the same machine-Windows7. Debugging into the Thrift code I saw the client's socket cannot connect to the server's local server. BTW, The same C# client connects to C+ server and python and c++ clients connect to the same python server. Just C#-->Python combination fails.
The problem looks similar to Connecting Python SocketServer with C# Client. I tried to modify the code following the answer in the link above but still, C# socket throws "No connection could be made because the target machine actively refused it 127.0.0.1:9091"
Client(C#):
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[1];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
Socket client = new Socket(ipAddress.AddressFamily,SocketType.Stream,
ProtocolType.Tcp);
TcpClient tcpClient = new TcpClient(AddressFamily.InterNetwork);
tcpClient.Client = client;
tcpClient.Connect(ip, port);
Why ipHostInfo.AddressList[1]? This selection takes IPv4 adapter from
ipconfig. I tries other indices as well. Server(Python, Inside
to Thrift-sever library):
res0 = socket.getaddrinfo(self.host,
self.port,
self._socket_family,
socket.SOCK_STREAM,
0,
socket.AI_PASSIVE |
socket.AI_ADDRCONFIG)
...
self.handle = socket.socket(res[0], res[1])
self.handle.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if hasattr(self.handle, 'settimeout'):
self.handle.settimeout(None)
self.handle.bind(res[4])
self.handle.listen(self._backlog)
client, addr = self.handle.accept()
It never exits from accept in case of C# client
You have too much duplicate code. Try following :
//client
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[1];
IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
TcpClient tcpClient = new TcpClient();
tcpClient.Connect(remoteEP);
//Server
IPEndPoint localEP = new IPEndPoint(IPAddress.Any, port);
TcpListener listener = new TcpListener(localEP);
listener.Start();
Related
Can i create socket server using custom Network IPAddress like (10.1.0.1 or 10.1.0.2)
ie
1.
TcpListener listener = new TcpListener(System.Net.IPAddress.Parse("10.1.1.1"), 8001);
2.
TcpListener listener = new TcpListener(System.Net.IPAddress.Parse("10.1.1.2"), 8002);
I need to use udp and tcp connections in my application,the TcpClient/TcpListener would rarely be active,but the udp one would be the main usage.
This is the server code:
static void Main(string[] args)
{
TcpListener listener = new TcpListener(IPAddress.Any, 25655);
listener.Start();
Socket sck = listener.AcceptTcpClient().Client;
UdpClient udpServer = new UdpClient(1100);
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
var data = udpServer.Receive(ref remoteEP);
string result = Encoding.UTF8.GetString(data);
Console.WriteLine(result);
Console.Read();
}
And this is the Client:
static void Main(string[] args)
{
TcpClient client = new TcpClient("127.0.0.1", 25655);
Socket sck = client.Client;
UdpClient udpclient = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1100); // endpoint where server is listening
udpclient.Connect(ep);
byte[] data = UTF8Encoding.UTF8.GetBytes("Hello");
udpclient.Send(data,data.Length);
}
I'm establishing the Tcp connection at first,then i'm trying to connect and send data from the client to the server.
From a breakpoint i add, i can see that the Tcp part works properly,the client finishes the program but in the server,it's hangs on the receiving part var data = udpServer.Receive(ref remoteEP);
like no data arrived..when i remove the tcp code part(the first 2 lines from the server and the client) it works great,shows the result message.
Does anyone know why im unable to get the data from the client?
Thanks in advance.
The main difference between UDP and TCP is that TCP is going to try to resend the message until the server tells the client it has received it. UDP is going to send and forget it even if the packet never reach or the host doesn't exist at all
Here is the flow of your code
Server starts up TCP
Client sends TCP
Server Receives TCP
Client sends UDP (server did not listen yet, packet lost but UDP doesn't care)
Server starts to listen to UDP
Server waiting for UDP to come <--- hang
You would like to do some multithread programming and start both of them at the same time before you tries to send message from the client.
The thing is that listener.AcceptTcpClient() blocks your current thread and UdpClient on server side is not established before Tcp connection created. In fact, your server is waiting for Tcp connection and only after that starting listening of Udp connections, while your client creates 2 connections one by one. My suggestions is - your server starting listening Udp port after the moment client actually sent data. The easiest way to check my suggestions - for client code add Thread.Sleep(1000) before sending data via UDP. In order to make that working you probably need to modify your code not blocking main thread but separate Tcp and Udp in the way similar to this:
static void Main(string[] args)
{
Task.Factory.StartNew(() =>
{
TcpListener listener = new TcpListener(IPAddress.Any, 25655);
listener.Start();
Socket sck = listener.AcceptTcpClient().Client;
// ToDo: further actions related to TCP client
}, TaskCreationOptions.LongRunning);
UdpClient udpServer = new UdpClient(1100);
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
var data = udpServer.Receive(ref remoteEP);
string result = Encoding.UTF8.GetString(data);
Console.WriteLine(result);
Console.Read();
}
client code can probably stay as it is for this example, but for real project I would recommend to separate that as well, as for sure you would like to get back some data from server via Tcp.
What if you first start the UDP client on server side and then establish the TCP connection between client and server?!
Server
static void Main(string[] args)
{
UdpClient udpServer = new UdpClient(1100);
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
TcpListener listener = new TcpListener(IPAddress.Any, 25655);
listener.Start();
Socket sck = listener.AcceptTcpClient().Client;
var data = udpServer.Receive(ref remoteEP);
string result = Encoding.UTF8.GetString(data);
Console.WriteLine(result);
Console.Read();
}
Client
static void Main(string[] args)
{
TcpClient client = new TcpClient();
client.Connect("127.0.0.1", 25655);
UdpClient udpclient = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1100); // endpoint where server is listening
udpclient.Connect(ep);
byte[] data = UTF8Encoding.UTF8.GetBytes("Hello");
udpclient.Send(data, data.Length);
}
Code server I have server listen on port 1450:
//Using UDP sockets
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
EndPoint ourEP = new IPEndPoint(IPAddress.Any, 1450);
//Listen asynchronously on port 1450 for coming messages (Invite, Bye, etc).
clientSocket.Bind(ourEP);
//Receive data from any IP.
EndPoint remoteEP = (EndPoint)(new IPEndPoint(IPAddress.Any, 0));
byteData = new byte[1024];
//Receive data asynchornously.
clientSocket.BeginReceiveFrom(byteData,
0, byteData.Length,
SocketFlags.None,
ref remoteEP,
new AsyncCallback(OnReceive),
null);
but code on not open port 1450 and client connect:
otherPartyIP = new IPEndPoint(IPAddress.Parse(txtCallToIP.Text), 1450);
otherPartyEP = (EndPoint)otherPartyIP;
When i run code client and server in lan network it's ok. but run over network i check port 1450 in lan not open. tell me how open port 1450 in code server? thanks
I created an application with server and client tool using sockets etc. When using my code on my computer works. Now I installed the Himachi software and I need to use this software in my application so that when a user connects with me, the application created could be used in this network. Note that this is my first time using sockets. The problem is that they are not connecting to each other and also it gives me this error on changing the ip and port: The requested address is not valid in its context
The send Tool
public Send(string Group, string port, string ttl, string rep, string data)
{
IPAddress ip;
try
{
Console.WriteLine("Send on Group: {0} Port: {1} TTL: {2}", Group,port,ttl);
ip = IPAddress.Parse(Group);
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ip));
s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, int.Parse(ttl));
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(Group),int.Parse(port));
Console.WriteLine("Connecting...");
s.Connect(ipep);
byte[] byData = System.Text.Encoding.ASCII.GetBytes(data);
s.Send(byData, SocketFlags.None);
Console.WriteLine("Closing Connection...");
s.Close();
}
catch(System.Exception e) { Console.Error.WriteLine(e.Message); }
}
The Receive tool
public string RecvData(string Group, string port)
{
string str = "";
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, int.Parse(port));
s.Bind(ipep);
IPAddress ip = IPAddress.Parse(Group);
s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ip,IPAddress.Any));
// Getting the data
byte[] buffer = new byte[1024];
int iRx = s.Receive(buffer);
str = System.Text.Encoding.ASCII.GetString(buffer, 0, buffer.Length);
// Closing a Socket
s.Close();
return str;
}
Thanks
So your problem is that you are trying to use a VPN (hamachi) to connect two apps the server and the client so that the client can receive messages from the server right? I think that the error given "The requested address is not valid in its context" is because you are using a VPN but I don't know how this can be solved sorry. What I think is that maybe you might also need the network id and password but again I'm not sure. Please keep us informed because this is a very interesting question.
How can I convert a string to RemoteEndPoint ?
RemoteEndPoint is a property of a Socket, so you'd need to create a Socket first:
IPEndPoint ip = new IPEndPoint(address, port);
Socket mySocket = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
So if you have a string something like "127.0.0.1:25", you need to grab the address and port components. Try myEndPointString.Split(":") to get the two components out.