SocketException was Unhandled by user code - iphone

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Text;
using System.Security.Authentication;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using Newtonsoft.Json.Linq;
namespace WebApplication1
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnPush_Click(object sender, EventArgs e)
{
pushMessage(txtDeviceID.Text.Trim(), txtPayload.Text.Trim());
}
public void pushMessage(string deviceID, string Mesaj)
{
int port = 2195;
String hostname = "ssl://gateway.sandbox.push.apple.com:2195";
String certificatePath = HttpContext.Current.Server.MapPath("PushNotifi.p12");
X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), "taxmann");
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
TcpClient client = new TcpClient(hostname, port);
SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
try
{
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Ssl3, false);
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)0); //The command
writer.Write((byte)0); //The first byte of the deviceId length (big-endian first byte)
writer.Write((byte)32); //The deviceId length (big-endian second byte)
writer.Write(HexStringToByteArray(deviceID.ToUpper()));
String payload = "{\"aps\":{\"alert\":{\body\":\"" + Mesaj + "\"},\"badge\":1,\"sound\":\"default\"}}";
writer.Write((byte)0);
writer.Write((byte)payload.Length);
byte[] b1 = System.Text.Encoding.UTF8.GetBytes(payload);
writer.Write(b1);
writer.Flush();
byte[] array = memoryStream.ToArray();
sslStream.Write(array);
sslStream.Flush();
client.Close();
lblResponse.Text = "Sucess..";
}
catch (System.Security.Authentication.AuthenticationException ex)
{
client.Close();
lblResponse.Text = ex.Message;
}
catch (Exception e)
{
client.Close();
lblResponse.Text = e.Message;
}
}
// The following method is invoked by the RemoteCertificateValidationDelegate.
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
else // Do not allow this client to communicate with unauthenticated servers.
return false;
}
private static byte[] HexStringToByteArray(String DeviceID)
{
//convert Devide token to HEX value.
byte[] deviceToken = new byte[DeviceID.Length / 2];
for (int i = 0; i < deviceToken.Length; i++)
deviceToken[i] = byte.Parse(DeviceID.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
return deviceToken;
}
}
}
This is my code. When I run this, then
SocketException was unhandled by user code
on line
TcpClient client = new TcpClient(host-name, port);
when googling system.net.sockets.socketexception and not recognize ssl://gateway.sandbox.push.apple.com:2195 host name
How can I fix this?
Basically this code is for sending Push Notifications to an iPhone application.
I'm using localhost as the server for sending the notification.

I think the problem is your hostname string:
int port = 2195;
String hostname = "ssl://gateway.sandbox.push.apple.com:2195";
TcpClient client = new TcpClient(hostname, port);
The port value (2195) is a separate constructor parameter, so I don't think you should be passing it in the hostname parameter, as well.
Also, the protocol (e.g. ssl://) shouldn't be part of the hostname. The SslStream tells .NET that this is SSL.
If you look at this similar question on stack overflow, you'll see that they use something like this:
int port = 2195;
String hostname = "gateway.sandbox.push.apple.com";
TcpClient client = new TcpClient(hostname, port);
P.S. I think you also had it right, in your original question on this subject

Related

Xamarin Forms Socket connection using IPV6 address

I have a sample Socket application that communicates between two devices using and IP address and port. The IPV4 IP-addresses work fine in the application but I cannot seem to get the correct information for the IPV6 IP-addresses.
I believe I understand what is being talked about in this article with regarding to the Zone ID for an IPV6 address
https://howdoesinternetwork.com/2013/ipv6-zone-id
and I also believe I understand what is being said here within that document:
If you want to ping a neighbor computer, you will need to specify the neighbor’s IPv6 Link-Local address plus the Zone ID of your computer’s network adapter that is going towards that computer.
i.e. I need to use the remote IPV6 address with the local device's Zone ID.
My problem is I cannot seem to figure out what the local device's (ios, android) Zone ID is for IPV6 addresses. I have uploaded my sample Xamarin Forms socket server and client code to GitHub and it can be accessed here.
Server Code: https://github.com/gceaser/AsyncSocket
Client Code: https://github.com/gceaser/AsyncSocketClient
I have the IP Addresses and ports defined in the App.xaml.cs for each project and a switch in each project to go back and forth between an IP V4 and V6 connection. (You should update the IP Addresses for your environment if you are trying to test this.) The V4 connection works but I cannot get the V6 connection to work. Any help would be greatly appreciated.
NOTE: To the best of my knowledge you cannot run the client and server on the same windows machine. Something weird about sockets not being able to communicate that way as I have document in one of my other StackOverflow post. Thus to test please run the server on a Windows box and the Client within iOS.
UPDATE:
Here is the code for the Server Socket connection:
using System;
using
System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xamarin.Forms;
using System.Collections.Generic;
namespace AsyncSocketServer
{
public class AsynchronousSocketListener
{
public static ManualResetEvent allDone = new ManualResetEvent(false);
public delegate void onMessageReceivedComplete(object sender, string message);
public delegate void onResponseMessageSent(object sender, string message);
public static event onMessageReceivedComplete MessageReceivedComplete;
public static event onResponseMessageSent ResponseMessageSent;
public AsynchronousSocketListener()
{
}
public async static Task StartListening(IPAddress pobj_IPAddress, int pi_Port)
{
try
{
//IPAddress ipAddress = IPAddress.Parse(pobj_IPAddress);
IPEndPoint localEndPoint = new IPEndPoint(pobj_IPAddress, pi_Port);
Socket listener = new Socket(pobj_IPAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
// Bind the socket to the local endpoint and listen for incoming connections.
listener.Bind(localEndPoint);
listener.Listen(100);
//ViewModelObjects.AppSettings.SocketStatus = ge_SocketStatus.e_Listening;
await Task.Delay(100);
while (true)
{
// Set the event to nonsignaled state.
allDone.Reset();
// Start an asynchronous socket to listen for connections.
Debug.WriteLine("Waiting for a connection on " + pobj_IPAddress + " at port " + pi_Port.ToString() + "...");
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
// Wait until a connection is made before continuing.
allDone.WaitOne();
}
}
catch (Exception e)
{
Debug.WriteLine("StartListening Error" + e.ToString());
}
Debug.WriteLine("Read To end class");
}
public static void AcceptCallback(IAsyncResult ar)
{
try
{
// Signal the main thread to continue.
allDone.Set();
// Get the socket that handles the client request.
Socket listener = (Socket)ar.AsyncState;
//If we have shut down the socket dont do this.
Socket handler = listener.EndAccept(ar);
// Create the state object.
StateObject state = new StateObject();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
catch (Exception e)
{
Debug.WriteLine("AcceptCallback Error" + e.ToString());
}
}
public static void ReadCallback(IAsyncResult ar)
{
try
{
string ls_ReceivedCommunicationContent = string.Empty;
string ls_ReturnCommunicationContent = string.Empty;
//string content = string.Empty;
// Retrieve the state object and the handler socket
// from the asynchronous state object.
StateObject state = (StateObject)ar.AsyncState;
Socket handler = state.workSocket;
// Read data from the client socket.
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
ls_ReceivedCommunicationContent = state.sb.ToString();
if (ls_ReceivedCommunicationContent.IndexOf("<EOF>") > -1)
{
//We need to take off the end of file marker
string ls_WorkContent = ls_ReceivedCommunicationContent.Replace("<EOF>", "");
ls_ReturnCommunicationContent = ls_WorkContent;
//Different than app
Device.BeginInvokeOnMainThread(() => {
MessageReceivedComplete(null, ls_WorkContent);
});
Send(handler, ls_ReturnCommunicationContent);
}
else
{
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
}
catch (Exception e)
{
Debug.WriteLine("ReadCallback Error" + e.ToString());
}
}
private static void Send(Socket handler, String data)
{
try
{
// Convert the string data to byte data using ASCII encoding.
byte[] byteData = Encoding.ASCII.GetBytes(data);
// Begin sending the data to the remote device.
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
Device.BeginInvokeOnMainThread(() => {
ResponseMessageSent(null, data);
});
}
catch (Exception e)
{
Debug.WriteLine("Send Error" + e.ToString());
}
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket handler = (Socket)ar.AsyncState;
// Complete sending the data to the remote device.
int bytesSent = handler.EndSend(ar);
Debug.WriteLine("Sent {0} bytes to client.", bytesSent);
handler.Shutdown(SocketShutdown.Both);
handler.Close();
}
catch (Exception e)
{
Debug.WriteLine("SendCallback Error" + e.ToString());
}
}
}
}
Here is the client Code:
using System;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace AsyncSocketClient
{
// This template use base socket syntax to change Pattern. (like Send, Receive, and so on)
// Convert to Task-based Asynchronous Pattern. (TAP)
public static class AsynchronousClientSocket
{
public static async Task<string> SendMessage(string ps_IPAddress, int pi_Port, string ps_Message)
{
string ls_response = "";
try
{
string ls_ReturnMessage = "";
// Establish the remote endpoint for the socket.
IPAddress ipAddress = IPAddress.Parse(ps_IPAddress);
IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, pi_Port);
// Create a TCP/IP socket.
var client = new Socket(ipAddress.AddressFamily,
SocketType.Stream, ProtocolType.Tcp);
// Connect to the remote endpoint.
var isConnect = await client.ConnectAsync(remoteEndPoint).ConfigureAwait(false);
if (!isConnect)
{
Console.WriteLine("Can not connect.");
return ls_ReturnMessage;
}
// Send test data to the remote device.
var bytesSent = await client.SendAsync(ps_Message + "<EOF>").ConfigureAwait(false);
Console.WriteLine("Sent {0} bytes to server.", bytesSent);
// Receive the response from the remote device.
ls_response = await client.ReceiveAsync().ConfigureAwait(false);
// Write the response to the console.
Console.WriteLine("Response received : {0}", ls_response);
// Release the socket.
client.Shutdown(SocketShutdown.Both);
client.Close();
}
catch (Exception ex)
{
Debug.WriteLine("Error: " + ex.Message);
}
return ls_response;
}
private static Task<bool> ConnectAsync(this Socket client, IPEndPoint remoteEndPoint)
{
if (client == null) throw new ArgumentNullException(nameof(client));
if (remoteEndPoint == null) throw new ArgumentNullException(nameof(remoteEndPoint));
return Task.Run(() => Connect(client, remoteEndPoint));
}
private static bool Connect(this Socket client, EndPoint remoteEndPoint)
{
if (client == null || remoteEndPoint == null)
return false;
try
{
client.Connect(remoteEndPoint);
return true;
}
catch (Exception)
{
return false;
}
}
private static async Task<string> ReceiveAsync(this Socket client, int waitForFirstDelaySeconds = 3)
{
if (client == null) throw new ArgumentNullException(nameof(client));
// Timeout for wait to receive and prepare data.
for (var i = 0; i < waitForFirstDelaySeconds; i++)
{
if (client.Available > 0)
break;
await Task.Delay(1000).ConfigureAwait(false);
}
// return null If data is not available.
if (client.Available < 1)
return null;
// Size of receive buffer.
const int bufferSize = 1024;
var buffer = new byte[bufferSize];
// Get data
var response = new StringBuilder(bufferSize);
do
{
var size = Math.Min(bufferSize, client.Available);
await Task.Run(() => client.Receive(buffer)).ConfigureAwait(false);
response.Append(Encoding.ASCII.GetString(buffer, 0, size));
} while (client.Available > 0);
// Return result.
return response.ToString();
}
private static async Task<int> SendAsync(this Socket client, string data)
{
var byteData = Encoding.ASCII.GetBytes(data);
return await SendAsync(client, byteData, 0, byteData.Length, 0).ConfigureAwait(false);
}
private static Task<int> SendAsync(this Socket client, byte[] buffer, int offset,
int size, SocketFlags socketFlags)
{
if (client == null) throw new ArgumentNullException(nameof(client));
return Task.Run(() => client.Send(buffer, offset, size, socketFlags));
}
}
}
When I start the serer, switch it to IPV6 and start it, I get the message that it is waiting for a connection as follows:
Waiting for a connection on fe80::cda4:ea52:29f5:2c7c at port 8080...
When I start the Client, switch it to IPV6 and attempt to send a message, I get the error:
2020-06-19 09:32:51.029902-0400 AsyncSocketClient.iOS[33593:9360848] Can not connect.

.NET 4.5 ASync TCP Server Memory Leak - BeginReceive/BeginSend

We needed a Windows Service that supported TCP communications with a number of clients. So I based it on the MSDN Async Example The thing with the Microsoft example is that the client sends one message to the server, the server then resends the message then closes. Great!
So having blindly deployed this to our prod and customer site we got reports that it had crashed. Looking at Prod we noticed that after 1 day, the memory usage grew to just under 1GB before throwing an OutOfMemoryException. Lots of testing here!
This happened with 1 client connected. It sends an XML based message that is quite large ~1200 bytes every second. Yes, every second.
The service then does some processing and sends a return XML message back to the client.
I've pulled the TCP Client/Server communications into a simple set of Console applications to replicate the issue - mainly to eliminate other managed/unmanaged resources. Now I've been looking at this for a number of days now and have pulled all of my hair and teeth out.
In my example I am focusing on the following classes:
B2BSocketManager (Server Listener, Sender, Receiver)
NOTE I have changed the code to return the whoopsy readonly byte array - not the sent message. I've also removed the new AsyncCallback(delegate) from the BeginReceive/BeginSend calls.
namespace Acme.OPC.Service.Net.Sockets
{
using Acme.OPC.Service.Logging;
using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
public class B2BSocketManager : ISocketSender
{
private ManualResetEvent allDone = new ManualResetEvent(false);
private IPEndPoint _localEndPoint;
private readonly byte[] whoopsy = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
public B2BSocketManager(IPAddress address, int port)
{
_localEndPoint = new IPEndPoint(address, port);
}
public void StartListening()
{
StartListeningAsync();
}
private async Task StartListeningAsync()
{
await System.Threading.Tasks.Task.Factory.StartNew(() => ListenForConnections());
}
public void ListenForConnections()
{
Socket listener = new Socket(_localEndPoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
Log.Instance.Info("B2BSocketManager Listening on " + _localEndPoint.Address.ToString() + ":" + _localEndPoint.Port.ToString());
try
{
listener.Bind(_localEndPoint);
listener.Listen(100);
while (true)
{
allDone.Reset();
Log.Instance.Info("B2BSocketManager Waiting for a connection...");
listener.BeginAccept(new AsyncCallback(ConnectCallback), listener);
allDone.WaitOne();
}
}
catch (Exception e)
{
Log.Instance.Info(e.ToString());
}
}
public void ConnectCallback(IAsyncResult ar)
{
allDone.Set();
Socket listener = (Socket)ar.AsyncState;
Socket handler = listener.EndAccept(ar);
handler.DontFragment = false;
handler.ReceiveBufferSize = ClientSocket.BufferSize;
Log.Instance.Info("B2BSocketManager Client has connected on " + handler.RemoteEndPoint.ToString());
ClientSocket state = new ClientSocket();
state.workSocket = handler;
handler.BeginReceive(state.buffer, 0, ClientSocket.BufferSize, 0, new AsyncCallback(ReadCallback), state); // SocketFlags.None
}
public void ReadCallback(IAsyncResult ar)
{
String message = String.Empty;
ClientSocket state = (ClientSocket)ar.AsyncState;
Socket handler = state.workSocket;
int bytesRead = handler.EndReceive(ar);
if (bytesRead > 0)
{
Console.WriteLine("Received " + bytesRead + " at " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
message = Encoding.ASCII.GetString(state.buffer, 0, bytesRead);
if (!string.IsNullOrEmpty(message))
{
Send(handler, message);
}
handler.BeginReceive(state.buffer, 0, ClientSocket.BufferSize, 0, ReadCallback, state);
}
}
public void Send(Socket socket, string data)
{
// just hard coding the whoopse readonly byte array
socket.BeginSend(whoopsy, 0, whoopsy.Length, 0, SendCallback, socket);
}
private void SendCallback(IAsyncResult ar)
{
Socket state = (Socket)ar.AsyncState;
try
{
int bytesSent = state.EndSend(ar);
}
catch (Exception e)
{
Log.Instance.ErrorException("", e);
}
}
}
}
ClientSender (Client Sender)
The client sends an xml string to the server every 250 milliseconds. I wanted to see how this would perform. The xml is slightly smaller than what we send on our live system and is just created using a formatted string.
namespace TestHarness
{
using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
class ClientSender
{
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static void StartSpamming(Socket client)
{
while(true)
{
string message = #"<request type=""da"">{0}{1}</request>" + Environment.NewLine;
Send(client, string.Format(message, "Be someone" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), String.Concat(Enumerable.Repeat("<test>Oooooooops</test>", 50))));
Thread.Sleep(250);
}
}
public static void Connect(EndPoint remoteEP)
{
Socket listener = new Socket(remoteEP.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listener.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), listener);
connectDone.WaitOne();
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
Socket client = (Socket)ar.AsyncState;
// Complete the connection.
client.EndConnect(ar);
Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString());
// Signal that the connection has been made.
connectDone.Set();
System.Threading.Tasks.Task.Factory.StartNew(() => StartSpamming(client));
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(Socket client, String data)
{
byte[] byteData = Encoding.ASCII.GetBytes(data);
client.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(SendCallback), client);
}
private static void SendCallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
int bytesSent = client.EndSend(ar);
Console.WriteLine("Sent {0} bytes to server " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), bytesSent);
sendDone.Set();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Receive(Socket client)
{
try
{
StateObject state = new StateObject();
state.workSocket = client;
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
int bytesRead = client.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
else
{
if (state.sb.Length > 1)
{
string response = state.sb.ToString();
}
receiveDone.Set();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
State Class
All I wanted was a read buffer to strip the message out of and try and load into XML. But this has been removed from this cut down version to see the issues with just the sockets.
using System;
using System.Linq;
using System.Net.Sockets;
namespace Acme.OPC.Service.Net.Sockets
{
public class ClientSocket
{
public Socket workSocket = null;
public const int BufferSize = 4096;
public readonly byte[] buffer = new byte[BufferSize];
}
}
I've shared my code here:
Explore One Drive Share
I've been profiling things using my Telerik JustTrace Profiler. I just start the server app then start the client app. This is on my Windows 7 64-bit VS2013 development environment.
Run 1
I see Memory Usage is around 250KB with the Working Set at around 20MB. The time seems to tick along nicely, then all of a sudden the memory usage will step up after around 12 minutes. Though things vary.
It would also appear that after the ~16:45:55 (Snapshot) when I Force GC, the memory starts going up each time I press it as opposed to leaving it running and upping automatically which might be an issue with Telerik.
Run 2
Then if I am creating the array of bytes within the Send with (which is more of what the service does - sends an appropriate response string to the client):
public void Send(Socket socket, string data)
{
byte[] byteData = Encoding.ASCII.GetBytes(data);
socket.BeginSend(byteData, 0, byteData.Length, 0, SendCallback, socket);
}
We can see the memory going up more:
Which brings me to what is being retained in memory. I see a log of System.Threading.OverlappedData and I have noticed ExecutionContexts in there. The OverlappedData has a reference to a byte array this time.
With Roots Paths to GC
I am running the profiling overnight so will hopefully get to add more info to this in the morning. Hopefully somebody can point me in the right direction before that - if I'm doing something wrong and I am too blind/silly to see it.
And here are the results of running overnight:

UDP Index out of range

I am trying to figure out why the client component of the array below is out of range. I know this happens when the element of an array that you are trying to access doesn't exist but I am new to Socket Programming and trying to write my first UDP script but not sure how to deal with it.
Client side code causing error at the args[0]:
class EmployeeUDPClient{
public static void Main(string[] args){
UdpClient udpc = new UdpClient(args[0],2055); //Line causing error
IPEndPoint ep = null;
while(true){
Console.Write("Name: ");
string name = Console.ReadLine();
if(name == "") break;
byte[] sdata = Encoding.ASCII.GetBytes(name);
udpc.Send(sdata,sdata.Length);
byte[] rdata = udpc.Receive(ref ep);
string job = Encoding.ASCII.GetString(rdata);
Console.WriteLine(job);
}
}
}
This is the server side code which runs fine:
class EmployeeUDPServer{
public static void Main(){
UdpClient udpc = new UdpClient(2055);
Console.WriteLine("Server started, servicing on port 2055");
IPEndPoint ep = null;
while(true){
byte[] rdata = udpc.Receive(ref ep);
string name = Encoding.ASCII.GetString(rdata);
string job = ConfigurationSettings.AppSettings[name];
if(job == null) job = "No such employee";
byte[] sdata = Encoding.ASCII.GetBytes(job);
udpc.Send(sdata,sdata.Length,ep);
}
}
}
Any thoughts on why I get this error? I am running the 2 scripts on the same computer so could that be the reason?
The error is because you are not passing any arguments to the Main() function within your client class.
Change line:
UdpClient udpc = new UdpClient(2055);
To:
string[] host = new string[1];
host[0] = "127.0.0.1";
UdpClient udpc = new UdpClient(host);

Using SSL Stream with Asynchronous System.Net.Sockets

My server is now running using Asynchronous System.Net.Sockets but i want to use SSL stream with it. i am pretty new to using SSL so here is my server code if someone can help me with it
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
public class Wrapper
{
public byte[] buffer;
public Socket _socket;
public object connector;
}
public class WinSocket
{
private Dictionary<string, byte> Connections;
public event Action<Wrapper> AnnounceNewConnection;//Event Handlers
public event Action<Wrapper> AnnounceDisconnection;
public event Action<byte[], Wrapper> AnnounceReceive;
private Socket _socket;
public int MAX_USER_CONNECTIONS = 2;//Max User Connections
public WinSocket(ushort port)
{
try
{
Connections = new Dictionary<string, byte>();
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.Bind(new IPEndPoint(IPAddress.Any, port));
_socket.Listen(500);
_socket.BeginAccept(AcceptConnections, new Wrapper());
}
catch (Exception e)
{
Console.WriteLine(e);//write an exception
}
}
private void AcceptConnections(IAsyncResult result)
{
try
{
Wrapper wr = result.AsyncState as Wrapper;
wr._socket = _socket.EndAccept(result);
#region Invisible
string IP = wr._socket.RemoteEndPoint.ToString().Split(':')[0].ToString();//Get user ip
if (!Connections.ContainsKey(IP))
Connections.Add(IP, 1);
else
if (Connections[IP] <= MAX_USER_CONNECTIONS)//Maximum Connections Per IP
{
byte connections = Connections[IP];
Connections.Remove(IP);//Limit exceeded
Connections.Add(IP, (byte)(connections + 1));
}
else
{
wr._socket.Disconnect(false);
_socket.BeginAccept(AcceptConnections, new Wrapper());
return;
}
#endregion
wr.buffer = new byte[65535];
wr._socket.BeginReceive(wr.buffer, 0, 65535, SocketFlags.None, ReceiveData, wr);
AnnounceNewConnection.Invoke(wr);
_socket.BeginAccept(AcceptConnections, new Wrapper());
}
catch (Exception e)
{
Console.WriteLine(e);//write an exception
}
}
private void ReceiveData(IAsyncResult result)//Receiving Data
{
try
{
Wrapper wr = result.AsyncState as Wrapper;
string IP = wr._socket.RemoteEndPoint.ToString().Split(':')[0].ToString();//Get UIP
if (Connections.ContainsKey(IP))
{
SocketError error = SocketError.Disconnecting;
int size = wr._socket.EndReceive(result, out error);
if (error == SocketError.Success && size != 0)
{
byte[] buffer = new byte[size];
Buffer.BlockCopy(wr.buffer, 0, buffer, 0, size);
AnnounceReceive.Invoke(buffer, wr);//The delegate
if (wr._socket.Connected)//Make sure socket is connected
wr._socket.BeginReceive(wr.buffer, 0, 65535, SocketFlags.None, ReceiveData, wr);//Start Receiving Data
}
else
{
if (wr._socket.Connected)
{
wr._socket.Disconnect(true);//Disconnect the client
}
byte connections = Connections[IP];
Connections.Remove(IP);
Connections.Add(IP, (byte)(connections - 1));
try
{
AnnounceDisconnection.Invoke(wr);
}
catch { }
}
}
}
catch (Exception e)
{
Console.WriteLine(e);//write an exception
}
}
}
So my question again clearly is : How to use SSL Stream with socket class like the ABOVE code
Replace the Stream class with the System.Net.SslStream class. In addition to the above code, call AuthenticateAsServer and pass the server SSL certificate in the WinSocket constructor.

Iphone push notification issue

I am working on iphone push notification. I can able to get my device token. I am using .net for pushing json data. But the issue is i cant get the notification. I just want to know whether .net has to push json data over in hosted machine?
Regards,
sathish
I believe that is related to:
Add iPhone push notification using ASP.NET server
Read through the linked project in there. It is pretty comprehensive. You can actually just use that library... it is pretty good.
Unless I misunderstood the question?
Use following snippet to send Push Notification
public void PendingNotification(string DeviceToken,string message)
{
try
{
int port = 2195;
//Developer
String hostname = "gateway.sandbox.push.apple.com";
//Production
//String hostname = "gateway.push.apple.com";
String certificatePassword = "XXXXXXX";
string certificatePath = Server.MapPath("~/cer.p12");
TcpClient client = new TcpClient(hostname, port);
X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), certificatePassword);
X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
//String DeviceToken = "XXXXXXXXXXXX";
String LoginName = "Name";
int Counter = 1; //Badge Count;
String Message = message;
String UID = "your choice UID";
string payload = "{\"aps\":{\"alert\":\"" + Message + "\",\"badge\":" + Counter + ",\"sound\":\"default\"},\"UID\":\"" + UID + "\",\"LoginName\":\"" + LoginName + "\"}";
MemoryStream memoryStream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(memoryStream);
writer.Write((byte)0);
writer.Write((byte)0);
writer.Write((byte)32);
writer.Write(HexStringToByteArray(DeviceToken.ToUpper()));
writer.Write((byte)0);
writer.Write((byte)payload.Length);
byte[] b1 = System.Text.Encoding.UTF8.GetBytes(payload);
writer.Write(b1);
writer.Flush();
byte[] array = memoryStream.ToArray();
sslStream.Write(array);
}
catch (Exception ex)
{
//Response.Write(ex.Message);
}
}
public static byte[] HexStringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length)
.Where(x => x % 2 == 0)
.Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
.ToArray();
}
public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (sslPolicyErrors == SslPolicyErrors.None)
return true;
Console.WriteLine("Certificate error: {0}", sslPolicyErrors);
return false;
}