Windows phone silverlight socket HostNotFound error - c#

I am getting HostNotFound error while trying to connect with socket in async. I am sure, that host is working. The strangest part is that all emulator starting from "8.1 u1 *" dont give such error. They connect without any problems. Only my device (htc windows phone 8s) and emulators without 8.1 getting this error. Host address 109.235.68.205 and port 6005. I am targeting 8.0 windows phone. I have no ideas how to solve it.
public string Connect(string hostName, int portNumber)
{
string result = string.Empty;
// Create DnsEndPoint. The hostName and port are passed in to this method.
DnsEndPoint hostEntry = new DnsEndPoint(hostName, portNumber);
// Create a stream-based, TCP socket using the InterNetwork Address Family.
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Create a SocketAsyncEventArgs object to be used in the connection request
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = hostEntry;
// Inline event handler for the Completed event.
// Note: This event handler was implemented inline in order to make this method self-contained.
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
// Retrieve the result of this request
result = e.SocketError.ToString();
// Signal that the request is complete, unblocking the UI thread
_clientDone.Set();
if(OnConnect != null)
OnConnect(true, new ConnectionEventArgs() { Response = result });
});
// Sets the state of the event to nonsignaled, causing threads to block
_clientDone.Reset();
// Make an asynchronous Connect request over the socket
_socket.ConnectAsync(socketEventArg);
// Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
// If no response comes back within this time then proceed
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
return result;
}

I was able to successfully run your code on the Windows Phone 8 emulators targeting one of my network machines.
The socket.ConnectAsync call is already an Async request that wouldn't block your UI so I don't think you require the manual steps to manage thread synchronization.
But if you insist on this implementation, you can replace the DnsEndPoint with IPEndpoint in your code.
IPEndPoint hostEntry = new IPEndPoint(IPAddress.Parse(hostName), portNumber);
Hope this helps.

Related

System.Net.Sockets.UdpClient not receiving multicast messages

I'm working on a UWP/Xamarin.Android app that uses SSDP multicast search to detect other devices on the local network that are running the same app. I've been able to send out multicast messages with UdpClient, but I'm not able to receive multicast messages. It hangs on UdpClient.ReveiveAsync() and never receives a message. Any help in getting this to work would be greatly appreciated.
Here's the coding I'm using to initialize the UdpClient and receive messages:
protected override Task CreateResourcesAsync()
{
address = IPAddress.Parse(Settings.Address ?? "239.255.255.250");
port = Settings.Port ?? 1900;
IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);
client = new UdpClient() { MulticastLoopback = true };
client.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
// This line was to test setting SO_REUSE_MULTICASTPORT on Windows, it didn't help
//client.Client.SetSocketOption(SocketOptionLevel.Socket, (SocketOptionName)0x3008, true);
client.Client.Bind(localEndPoint);
client.JoinMulticastGroup(address);
Task.Run(ReceiveThread);
return Task.CompletedTask;
}
async Task ReceiveThread()
{
while (IsActive && client != null)
{
// Does not receive any messages so the Task returned from client.ReceiveAsync() does not complete
UdpReceiveResult request = await client.ReceiveAsync();
}
}
I've tried using different multicast addresses and ports other than the SSDP ones, I've also tried binding to both IPAddress.Any and my local IP address, but neither works.
I'm able to receive multicast messages using the WinRT DatagramSocket, but I can't continue to use WinRT as the app needs to run on Android. I'll include my DatagramSocket code just in case it can be used to help somehow:
DatagramSocket socket = new DatagramSocket();
// If MulticastOnly is not true, it will bind to the port but won't receive messages
socket.Control.MulticastOnly = true;
socket.MessageReceived += async (sender, args) =>
{
// Immediately receives SSDP search requests from various devices on my network
};
await socket.BindServiceNameAsync("1900");
socket.JoinMulticastGroup("239.255.255.250");

Reopen Tcp socket on the same port

I have a socket that serves a single request-response purpose.
I set it up on port XXX let it wait for a connection, read the data and reply with some data.
I would like to open a new socket on the same port. As soon as the response was sent.
That is handled externally (there is a manager that is checking the state of the thread and if it was used it disposes it and creates a new one.
The problem is that it gets blocked on
_socket = _socket.Accept();
and when a new client tries to connect it never leaves this line. (And client gets no reply).
The socket is running in
new Thread(Run);
and here is my Run method:
private void Run()
{
var ipHostInfo = Dns.Resolve(Dns.GetHostName());
var ipAddress = ipHostInfo.AddressList[0];
var localEndPoint = new IPEndPoint(ipAddress, Port);
_socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
try
{
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_socket.Bind(localEndPoint);
_socket.Listen(100);
_socket = _socket.Accept();
var data = string.Empty;
while (true)
{
var bytes = new byte[1024];
var bytesRec = _socket.Receive(bytes);
data += Encoding.UTF8.GetString(bytes, 0, bytesRec);
if (data.IndexOf("<EOF>", StringComparison.Ordinal) <= -1) continue;
var dataWithoutEof = data.Substring(0, data.IndexOf("<EOF>", StringComparison.Ordinal));
//TODO: do smt with the data
break;
}
var byteData = Encoding.UTF8.GetBytes("testResponse" + "<EOF>");
_socket.Send(byteData);
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
I suppose that I am not closing the existing socket correctly.
You code is wrong you should not expect this method to exit because you want your server up and running the whole time. I am assuming here you call run several times. Don't do that.
The code becomes then something like this :
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_socket.Bind(localEndPoint);
_socket.Listen(100);
while (true)
{
var _servicingsocket = _socket.Accept();
....
_servicingsocket.close();
}
accept is a blocking call. That waits for a new connection.
_socket is a listening socket and must be kept during the lifetime of the server.
A TCP connection is based on the notion of a socket pair.
When the server starts you have a single socket that listens on port 100.
Suppose a connection is established, then accept returns what is called a servicing socket that is basically a clone from the listening socket. This means that it is also using source port 100, but because it is a servicing socket it belongs to a socket pair that identifies the connection. A socket pair is the combination of 2 sockets, your own socket and the peer. When a data comes in, TCP will iterate through the socket pairs to find the right socket.
An additional advantage of doing it this way is that you allow other connection attempts to queue up on the listening socket while you are processing the first request. Your _socket is overwritten with the servicing socket and you are then assuming that the listening socket is going to be garbage collected. I am not sure if this is going to happen because I haven't tried it like you are doing it in your code because it is a bad idea in the first place because it implements idisposable. (https://msdn.microsoft.com/en-us/library/system.net.sockets.socket%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396) If you really want to close the server you have to make sure to close both the servicing socket and the listening socket to make the code clean.

Creating a Socket Connection in Store App not Working

I have just released an app to the Windows Phone Store, after thoroughly debugging, and the functionality when testing in debug and release mode is not the same as when I use the app that was downloaded from the store. When testing in debug and release mode from my solution I have no issues (on device or on emulator) and everything works great. After downloading from the store I only return the SocketError.NetworkDown error?
I am creating a Socket connection to gather network interface information.
private async void UpdateCurrentInterface()
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// To run this application you should specify the name of a server on your network that is running
// the required service.
string serverName = "www.bing.com";
// This identifies the port over which to communicate.
int portNumber = 80;
// Create DnsEndPoint.
DnsEndPoint hostEntry = new DnsEndPoint(serverName, portNumber);
// Create a SocketAsyncEventArgs object to be used in the connection request.
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = hostEntry;
socketEventArg.UserToken = socket;
socketEventArg.Completed += ShowNetworkInterfaceInformation1;
// // Make an asynchronous Connect request over the socket.
socket.ConnectAsync(socketEventArg);
}
/// <summary>
/// Display the network information using the GetCurrentNetworkInterface extension method on the socket.
/// </summary>
/// <remarks>This is the callback from the ConnectAsync method.</remarks>
private void ShowNetworkInterfaceInformation1(object s, SocketAsyncEventArgs e)
{
// When ConnectAsync was called it was passed the socket object in
// the UserToken field of the socketEventArg. This context is retrieved once
// the ConnectAsync has completed.
Socket socket = e.UserToken as Socket;
// Only call GetCurrentNetworkInterface if the connection was successful.
if (e.SocketError == SocketError.Success)
{
NetworkInterfaceInfo netInterfaceInfo = socket.GetCurrentNetworkInterface();
// We are making UI updates, so make sure these happen on the UI thread.
Dispatcher.BeginInvoke(() =>
{
currentTypeTextBlock.Text = GetInterfaceTypeString(netInterfaceInfo.InterfaceType);
currentNameTextBlock.Text = name = netInterfaceInfo.InterfaceName;
string change = "";
if (netInterfaceInfo.InterfaceState.ToString() == "Connected")
currentStateTextBlock.Text = "connected";
else
currentStateTextBlock.Text = "disconnected";
});
}
else if (e.SocketError == SocketError.NetworkDown)
{
DisplayMessage("Could not connect.", "Network Down Error", MessageBoxButton.OK);
}
// Close our socket since we no longer need it.
socket.Close();
}
Include ID_CAP_NETWORKING as a capability within WMAppManifest.

UDP reception in windows 7.x mobile

I am having an issue with Windows Mobile.
I was writing a code for recieving UDP data from a windows server Aplication (created by me), which broadcasts data, but, when the windows application executes, I am encoutering a terrible issue:
An invalid argument was supplied
when the socket ReceiveFromAsync() funciton works.
Can anyone help me please?
--- this is the code
public string Receive(int portNumber)
{
string response = "Operation Timeout";
// We are receiving over an established socket connection
registerSocket();
if (_socket != null)
{
// Create SocketAsyncEventArgs context object
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = new IPEndPoint(IPAddress.Any, portNumber);
// Setup the buffer to receive the data
socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
// Inline event handler for the Completed event.
// Note: This even handler was implemented inline in order to make this method self-contained.
socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e)
{
if (e.SocketError == SocketError.Success)
{
// Retrieve the data from the buffer
response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
response = response.Trim('\0');
}
else
{
response = e.SocketError.ToString();
}
_clientDone.Set();
_socket.ReceiveFromAsync(socketEventArg);
});
// Sets the state of the event to nonsignaled, causing threads to block
_clientDone.Reset();
// Make an asynchronous Receive request over the socket
**_socket.ReceiveFromAsync(socketEventArg);** // here the issue arises An //invalid argument was supplied
// Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
// If no response comes back within this time then proceed
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
}
else
{
response = "Socket is not initialized";
}
return response;
}
I have found the solution.
To receive Udp multicast you should call _socket.Bind(IPEndpoint) before receiving and use _socket.ReceiveAsync() instead of _socket.ReceiveFromAsync(). Also socketEventArg.RemoteEndpoint should be empty.
This code works for me:
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.SetBuffer(new byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE);
args.Completed += args_Completed;
_socket.Bind(new IPEndPoint(IPAddress.Any, **your port**));
_socket.ReceiveAsync(args);

Socket's state changes from Connected to Disconnected

I have two applications, one connects to another via TCP Socket. I was having an issue and after a long troubleshooting I begun to think the root cause is due to the disconnection of the Socket, aka the Socket.state changes to Disconnected.
The reasons I came to above conclusion are just purely from reading the codes and analyze them. I need to prove that is the case and therefore my question is have you ever came accross this type of issue that the socket actually keep getting disconnected even after trying to connect to them?
Below is my Connect code, I have a loop that constantly check for the socket's state itself, if I detect the state is "Disconnected" I call this Connect() function again. Upon each and every time I call Connect() I noticed my socket state is back to Connected again.
So my questions are:
1. Have you seen this behavior yourself before?
2. Do you see any problem in me calling multiple Connect() again and again?
3. Is there a way to simulate this type of socket disconnections? I tried but I can't set the Socket.Connected flag.
public override void Connect()
{
try
{
sState = Defs.STATE_CONNECTING;
// send message to UI
string sMsg = "<Msg SocketStatus=\"" + sState + "\" />";
HandleMessage(sMsg);
// Create the socket object
sSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
string sIP = "";
// Define the Server address and port
if (Validate.IsIPAddress(sServer.ToString()))
{
sIP = sServer.ToString();
}
else
{
IPHostEntry iphost = Dns.GetHostEntry(sServer.ToString());
sIP = iphost.AddressList[0].ToString();
}
IPEndPoint epServer = new IPEndPoint(IPAddress.Parse(sIP), 1234);
// Connect to Server non-Blocking method
sSock.Blocking = false;
AsyncCallback onconnect = new AsyncCallback(OnConnect);
sSock.BeginConnect(epServer, onconnect, sSock);
}
catch (Exception ex)
{
LogException(new Object[] { ex });
}
}

Categories

Resources