Can't make TCP client code work without USB cable attached - c#

I'm having a bit of trouble in getting a very simple TCP client working on my HTC Titan w/ Windows Phone 7.5.
When the USB cable is attached to the phone, the TCP client works like a charm, but as soon as the cable is unplugged, the client is unable to connect to a TCP server running on my development machine. The devices are on the same network and I'm using the explicit IP-address of my desktop machine to connect, so there's no name resolution going on afaik.
Here's the code I use. Most of it was taken from the Sockets samples on MSDN (can't seem to find the link now though).
private Socket _sock = null;
private ManualResetEvent _done = new ManualResetEvent(false);
private const int TIMEOUT = 5000;
//connect to server
public string Connect(string ip, int port) {
string result = string.Empty;
var host = new IPEndpoint(IPAddress.Parse(ip), port);
_sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_sock.SetNetworkRequirement(NetworkSelectionCharacteristics.NonCellular);
var args = new SocketAsyncEventArgs();
args.RemoteEndPoint = host;
args.Completed += new EventHandler((s,e) => {
result = e.SocketError.ToString();
_done.Set();
});
_done.Reset();
_sock.ConnectAsync(args);
_done.WaitOne(TIMEOUT);
return result;
}
//send message
public string Send(string msg) {
string response = "Operation timeout";
if (_sock != null) {
var args= new SocketAsyncEventArgs();
args.RemoteEndPoint = _sock.RemoteEndPoint;
args.Completed += new EventHandler(s, e) => {
response = e.SocketError.ToString();
_done.Set();
});
var payload = Encoding.UTF8.GetBytes(data);
args.SetBuffer(payload, 0, payload.Length);
_done.Reset();
_sock.SendAsync(args);
_done.WaitOne(TIMEOUT);
}
return response;
}
//receive message
public string Receive() {
string response = "Operation timeout";
if (_sock != null) {
var args= new SocketAsyncEventArgs();
args.RemoteEndPoint = _sock.RemoteEndPoint;
args.SetBuffer(new Byte[MAX_BUFSIZE], 0, MAX_BUFSIZE);
args.Completed += new EventHandler((s,e) => {
if (e.SocketError == SocketError.Success) {
response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
response = response.Trim('\0');
}
else {
response = e.SocketError.ToString();
}
_done.Set();
});
_done.Reset();
_sock.ReceiveAsync(args);
_done.WaitOne(TIMEOUT);
}
return response;
}
The code is then simply used like:
Connect(...);
Send(...);
Receive(...);
//and then close the socket
As I said before, the code works like a charm when the device is attached to my development machine. When the cable is unplugged, the connection phase just times out (regardless of the timeout interval I should say).
Also, the manifest contains the ID_CAP_NETWORKING capability which as I understand it should give the app permission to access the network.
Any ideas?
EDIT:
I discovered that switching to UDP communication works like a charm. Which means that the problem is that for some reason, the phone is unable to set up a persistant TCP connection to my dev machine. This is getting stranger by the minute.

Do you have a wireless ap nearby on which your phone is connected? because when you plug it in the pc it uses the pc's network connection.

You should check the IP address that you have on both the phone (from your code) and on the PC (which it looks like you've already found using ipconfig in your command prompt).
These should be in the same IP address range, and so start with the same digits (for IPv4, probably something link 192.168.0.*).
If this all matches up check your wireless router hasn't enabled a security setting which means that it doesn't allow TCP traffic from your phone to your PC.
If this is a consumer router you manage this should be fairly simple to verify (and potentially fix). If not, you're probably stuck...

Related

Socket communication - if (socket.Connected) sometimes stuck false on specific IP address even after reboot

I use socket communication in a Unity mobile application. The app communicate with different devices. It works 99% of the time, but sometimes the "socket.Connected" part stuck false even, when the device is available (from other instance of the app). So the issue is local. The problem presist even after the app is restarted or even after the phone rebooted! But after some time it works again.
It only stuck with one IP address. (For example with 192.168.1.4 not works, but with 192.168.1.5 works)
So the big question is: What can cause this issue so deep, that even rebooting the phone, does not fix.
static void Thread(object cData)
{
ConnectionData cdata = (ConnectionData)cData;
ConnectAsync(cdata);
}
static void ConnectAsync(ConnectionData cdata)
{
Device device = cdata.device;
string[] messages = cdata.messages;
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
try
{
socket.ReceiveTimeout = timeoutMs;
socket.SendTimeout = timeoutMs;
IPAddress ipAdd = IPAddress.Parse(device.IP);
IPEndPoint remoteEP = new IPEndPoint(ipAdd, device.Port);
IAsyncResult result = socket.BeginConnect(remoteEP, null, null);
result.AsyncWaitHandle.WaitOne(timeoutMs);
if (socket.Connected) // <--THE_PROBLEM = This stuck FALSE
{
...code...
}
}
...
}

Public TCP server with C# hosted on my computer

I'm trying to run a game TCP/UDP server on my computer. It's working fine within the local network, but when I'm trying to run the server with my public IP, it just doesn't work. I've tried to disable the firewall in my router, set port forwarding for port 17000 and added a firewall rule to my computer. I've also bound IP to my computer.
I've checked client calls with Wireshark and I found out that the client (Unity game) is sending data to my IP, but it's giving TCP Retransmission error for every TCP packet that it is trying to send.
There is some of the code from server and client.
Server IP is set to 192.168.0.*:17000
And the client is connecting to my IP with port 17000
SERVER:
public static void Start(byte _maxPlayers)
{
MaxPlayers = _maxPlayers;
Port = 17000;
Console.WriteLine("Starting server..");
InitializeServerData();
tcpListener = new TcpListener(GetLocalIPAddress(), Port);
tcpListener.Start();
tcpListener.BeginAcceptTcpClient(new AsyncCallback(TCPConnectCallback), null);
udpListener = new UdpClient(Port, GetLocalIPAddress().AddressFamily);
udpListener.BeginReceive(UDPReceiveCallback, null);
Console.WriteLine($"Server started on {tcpListener.LocalEndpoint}.");
}
CLIENT:
public void Connect()
{
socket = new TcpClient
{
ReceiveBufferSize = dataBufferSize,
SendBufferSize = dataBufferSize
};
receiveBuffer = new byte[dataBufferSize];
socket.BeginConnect(instance.ip, instance.port, ConnectCallback, socket);
}
private void ConnectCallback(IAsyncResult _result)
{
socket.EndConnect(_result);
if (!socket.Connected)
return;
stream = socket.GetStream();
receivedData = new Packet();
stream.BeginRead(receiveBuffer, 0, dataBufferSize, ReceiveCallback, null);
}
So I've found out, that I have two-router set up, and because I was forwarding port 17000 just on one router, it didn't work.

HoloLens works as UDP server but not as client

I try to send data from my PC (server) to my HoloLens (client) in UWP apps.
My primary goal is to use "Windows.Networking.Sockets.DatagramSocket" for the HoloLens receiver because else the code does not work in unity.
I already accomplished the system with wrong roles. The HoloLens sends data to the PC but with "System.Net.Sockets.UdpClient" instead of DatagramSocket...
Here you can see the important code parts:
// Current client application on PC (using System.Net.Sockets...)
HostName serverIp = new HostName("192.168.0.109");
string port = "1337";
async void Client()
{
DatagramSocket socket = new DatagramSocket(); //creating socket
socket.MessageReceived += Socket_MessageReceived; //attach receive event
await socket.BindEndpointAsync(serverIp, port); //bind socket
}
async void Socket_MessageReceived(DatagramSocket sender,
DatagramSocketMessageReceivedEventArgs args) //receive event
{
Stream streamIn = args.GetDataStream().AsStreamForRead();
StreamReader reader = new StreamReader(streamIn);
string msg = await reader.ReadLineAsync();
Print("Message received: " + msg);
}
// Current Server application on HoloLens (using Windows.Networking.Sockets...)
IPAddress serverIp = IPAddress.Parse("192.168.0.109");
const int port = 1337;
async void Server()
{
var udpClient = new UdpClient();
var serverEP = new IPEndPoint(serverIp, port);
byte[] bytes = Encoding.ASCII.GetBytes("Hello from Client!"); //parse
await udpClient.SendAsync(bytes, bytes.Length, serverEP); //send
}
The PC succesfully receives the message from the HoloLens.
My problem: When I swap server and client application on the devices that the PC sends (with UdpClient) and the HoloLens receives (with DatagramSocket), the message is not received anymore.
Both devices have connection to the network, I disabled firewall at the PC and in both appxmanifests "PrivateNetworks" is enabled.
Does anybody can figure the reasons?
Kind Regards
I somehow made it work but I unfortunately can't tell the difference.
My problem now is that the communication only works in one direction. I can write to the socket and the message arrives but I can't send messages from the socket back.
When I want to write from a socket I must not use "socket.BindEndpointAsync()" but "socket.ConnectAsync()" right? But no matter if I use a DataWriter or the OutputStream attribute no message can be received by my actually working receiver.
writer = new DataWriter(socket.OutputStream);
writer.WriteString("test");
IBuffer buffer = Encoding.ASCII.GetBytes("test").AsBuffer();
await socket.OutputStream.WriteAsync(buffer);
Maybe somebody can help me.
Kind regards

How do I connect to a Windows Universal App StreamSocket from a Console Application?

I am listening for connections through a Windows Universal App and would like to connect to that App through a Windows Console Application. I have done some basic code which I think should connect but I get a timeout error from the console application.
{"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 192.168.0.5:1771"}
The windows universal app never even goes into the connection received function.
The Server (UWP):
public async void SetupServer()
{
try
{
//Create a StreamSocketListener to start listening for TCP connections.
Windows.Networking.Sockets.StreamSocketListener socketListener = new Windows.Networking.Sockets.StreamSocketListener();
//Hook up an event handler to call when connections are received.
socketListener.ConnectionReceived += SocketListener_ConnectionReceived;
//Get Our IP Address that we will host on.
IReadOnlyList<HostName> hosts = NetworkInformation.GetHostNames();
HostName myName = hosts[3];
//Assign our IP Address
ipTextBlock.Text = myName.DisplayName+":1771";
ipTextBlock.Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(255,0,255,0));
//Start listening for incoming TCP connections on the specified port. You can specify any port that' s not currently in use.
await socketListener.BindEndpointAsync(myName, "1771");
}
catch (Exception e)
{
//Handle exception.
}
}
The Client (Console Application):
static void Main(string[] args)
{
try
{
byte[] data = new byte[1024];
int sent;
string ip = "192.168.0.5";
int port = 1771;
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(ip), port);
TcpClient client = new TcpClient();
client.Connect(ipep); //**************Stalls HERE************
using (NetworkStream ns = client.GetStream())
{
using (StreamReader sr = new StreamReader(ns))
{
using (StreamWriter sw = new StreamWriter(ns))
{
sw.WriteLine("Hello!");
sw.Flush();
System.Threading.Thread.Sleep(1000);
Console.WriteLine("Response: " + sr.ReadLine());
}
}
}
}
catch (Exception e)
{
}
}
I have tested your code on my side and it can work well. So there is nothing wrong with your code. But I can reproduce your issue by running the server and client on the same device, the client will throw the same exception as you showed above. So please ensure you're connecting from another machine. We cannot connect to a uwp app StreamSocketListener from another app or process running on the same machine,this is not allowed. Not even with a loopback exemption.
Please also ensure the Internet(Client&Server) capability is enabled. And on the client you can ping the server 192.168.0.5 successfully.

IpMulticast Stops Working after network is lost and then reconnects after 10-15 mins

I am working on a c# based application which is sending messages continuously using Multi-casting. Every thing works fine. The clients at thereceiving end receives messages continuously till the network is disconnected. But when I reconnect the network the client machines on the same network don't receive any messages till I collect all the messages on the same machine via receiving code.
Send Code:
using (UdpClient udpclient = new UdpClient())
{
IPAddress multicastaddress = IPAddress.Parse("239.0.0.222");
try
{
udpclient.ExclusiveAddressUse = false;
udpclient.MulticastLoopback = false;
udpclient.JoinMulticastGroup(multicastaddress);
IPEndPoint remoteep = new IPEndPoint(multicastaddress, 8191);
int j = udpclient.Send(byteBuffer, byteBuffer.Length, remoteep);
}
catch (Exception e)
{
udpclient.DropMulticastGroup(multicastaddress);
udpclient.Close();
}
finally
{
udpclient.DropMulticastGroup(multicastaddress);
udpclient.Close();
}
});
Receive Code:
var udpClientDispose = new UdpClient(_settingsViewModel.SyncPort);
var ipEndPoint = new IPEndPoint(IPAddress.Any, 8191);
IPAddress multicastaddress = IPAddress.Parse("239.0.0.222");
udpClientDispose.JoinMulticastGroup(multicastaddress, "192.168.0.12");
var timeElapsedSinceMasterMessageReceived = new Stopwatch();
Stopwatch sw = new Stopwatch();
sw.Start();
while (sw.ElapsedMilliseconds < 5000)
{
udpClientDispose.Receive(ref ipEndPoint);
}
udpClientDispose.Close();`
It Seems like all messages are getting collected at my system and there is a network jam on the particular multicast address i.e "239.0.0.222". As if I try to change the address it works but not again on "239.0.0.222".
Anyone knows the exact reason why is this happening and any valid solution to this.
When you say "network is disconnected", I'm going to assume you disable the NIC or physically unplug the wire.
If you subscribe to a multicast group, the NIC driver is instructed to listen to traffic from specific MAC addresses. When the link goes down or the NIC is disabled, the NIC driver will stop to listen to that multicast group and you will have to resubscribe manually.
You can use the NetworkInformation class to subscribe to event information if a NIC goes up/down and use that to resubscribe accordingly.

Categories