Socket is an interface
between application and network
Ø
The application creates a socket
Ø
The socket type dictates the style of
communication
Ø
Once configured the application can pass data to
the socket for network transmission receive data from the socket (transmitted
through the network by some other host)
Purpose
Send
and receive data with TCP sockets in your Windows Runtime app using features in
the Windows.Networking.Sockets namespace. Store application is a sandbox
environment, So that we can implement restricted functionality only. Incase if
you want to call your desktop application or access any file from custom
location from store application, it’s not possible. So we can use windows
service and implement your custom functionality and access those functionality through socket
Sockets
provide a low-level interface for sending and receiving network data. The
primary classes for use with sockets include the following:
Ø DatagramSocket -
Used to support network communication using a UDP datagram socket.
Ø StreamSocket -
Used to support network communication using a TCP stream socket.
Ø StreamSocketListener - Used to support listening for an
incoming network connection using a TCP stream socket.
Implementing Socket Listener in Widows Service
Define
port number _portToListen = 39529;
This function
initializes the listener socket. It binds the listener socket to the port specified by PORT_TO_LISTEN
constant defined above to enable the Windows Store apps to
Connect to.
AcceptCallBack function will be called when any client issues connect request
to the Service.
private void InitializeListenerSocket()
{
//
Creates one SocketPermission object for access restrictions
_permission = new SocketPermission(NetworkAccess.Accept,
TransportType.ConnectionOriented,
"127.0.0.1", SocketPermission.AllPorts);
//
Ensures the code to have permission to access a Socket
_permission.Demand();
string localHost = Dns.GetHostName();
//IPAddress[]
ipAddrList = Dns.GetHostEntry(localHost).AddressList;
IPAddress[] ipAddrList = Dns.GetHostEntry("localhost").AddressList;
//Get
the IPv4 address. For some reasons, IPv6 address doesn't work.
//IPAddress
localIp = ipAddrList.FirstOrDefault(t => t.IsIPv6LinkLocal == false);
IPAddress localIp = ipAddrList.FirstOrDefault(t =>
t.AddressFamily == AddressFamily.InterNetwork);
try
{
//
Listening Socket object
Socket socketListener = null;
if (localIp != null)
{
_ipEndPoint = new IPEndPoint(localIp,
_portToListen);
// Create one Socket object to listen the incoming
connection
if (_ipEndPoint != null)
{
socketListener = new Socket(localIp.AddressFamily,
SocketType.Stream,
ProtocolType.Tcp);
try
{
// Associates a Socket with a local endpoint
socketListener.Bind(_ipEndPoint);
socketListener.Listen(100);
// Begins an asynchronous operation to accept an attempt
if
(AcceptRequestCallbackFuncPtr == null)
AcceptRequestCallbackFuncPtr = new AsyncCallback(AcceptClientRequestCallback);
socketListener.BeginAccept(AcceptRequestCallbackFuncPtr,
socketListener);
UploadLog.Debug("~: DSP Feedback Service Started - Listening at:
" +
socketListener.LocalEndPoint);
}
catch (Exception exc)
{
UploadLog.Debug("~: StartAcceptingClientRequest: Exception" + exc.Message);
}
}
}
else
{
UploadLog.Debug("~: IP Address is Invalid. Connect to the network and
restart the machine");
Stop();
}
}
catch (Exception ex)
{
UploadLog.Debug("~: Exception while IntializingListenerSocket" + ex.Message);
}
}
This function is the Accept
event handler for Connection requests coming into the service from the Windows
Store client.
private void AcceptClientRequestCallback(IAsyncResult ar)
{
// A new
Socket to handle the incoming client request.
try
{
//
Get Listening Socket object passed as a parameter in the BeginAccept method
above.
if (ar.AsyncState != null)
{
Socket listener = (Socket)ar.AsyncState;
UploadLog.Debug("~: AcceptClientRequestCallback: Received a client
request.");
// Create a new socket
Socket clientSocket =
listener.EndAccept(ar);
UploadLog.Debug("~: EndAccept: Received a client request.");
WaitForData(clientSocket);
// Begins an asynchronous operation to accept an attempt.
If the below code is not present,
//then the close and re-establishing the connection by the
Windows store client is not possible.
listener.BeginAccept(AcceptRequestCallbackFuncPtr, listener);
}
}
catch (Exception exc)
{
UploadLog.Debug("~: AcceptClientRequestCallback Exception: " + exc.Message);
}
}
public void WaitForData(Socket clientSocket)
{
try
{
//log.Debug("~:
Calling InsureRegISCurrent() to check for the latest AWS Cache file for
Registration");
//_awsWorker.InsureCachedRegistrationIsCurrent();
if (ReceiveCallbackFuncPtr == null)
ReceiveCallbackFuncPtr = new AsyncCallback(ReceiveCallback);
//
Creates one object array for passing data
byte[] buffer = new byte[70000];
object[] obj = new object[2];
obj[0] = buffer;
obj[1] = clientSocket;
UploadLog.Debug("~: Wait For Data Read");
clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None,
ReceiveCallbackFuncPtr, obj);
}
catch (SocketException ex)
{
UploadLog.Debug("~:
WaitForData Exception: " + ex.Message);
}
catch (Exception ex)
{
UploadLog.Debug("~: WaitForData Exception: " + ex.Message);
}
}
ReceiveCallback: This is a callback function that gets called
when any incoming message is received.
This function receives the incoming file path, updates the
Concurrent queue and sets an event.
There is a separate
thread that is waiting on this event. On triggering this event, the file is
picked up
public void ReceiveCallback(IAsyncResult ar)
{
try
{
//
Fetch a user-defined object that contains information
object[] obj;
obj = (object[])ar.AsyncState;
UploadLog.Debug("~: ReceiveCallback: calling Receiving callback");
if (ar.AsyncState != null)
{
UploadLog.Debug("~: ReceiveCallback: AsyncState != null");
// Received byte array
byte[] buffer = (byte[])obj[0];
// A Socket to handle communication with the client.
Socket clientSocket = (Socket)obj[1];
if (clientSocket != null)
{
UploadLog.Debug("~: ReceiveCallback: clientSocket != null");
// Received message
string content = string.Empty;
int bytesRead = 0;
//bytesRead = clientSocket.EndReceive(ar);
if (clientSocket.Connected)
{
// The number of bytes received.
bytesRead =
clientSocket.EndReceive(ar);
UploadLog.Debug("~: ReceiveCallback: clientSocket.Connected");
}
if (bytesRead > 0)
{
UploadLog.Debug("~: ReceiveCallback: bytesRead > 0");
content += Encoding.ASCII.GetString(buffer,
0, bytesRead);
// If message contains "##EOS##", finish
receiving
if (content.Length > 0)
{
// Convert byte array to string
string str =
content.Substring(0, content.Length);
HsdFilledMessage
response = new HsdFilledMessage();
UploadLog.Debug("~: " + String.Format("ReceiveCallback:
New message received. Bytes read: {0}, File to Upload: {1}", bytesRead, str));
HsdFilledMessage Message
= RestoreAsync<HsdFilledMessage>(str);
UploadLog.Debug("~: ReceiveCallback:
Completed Datacontract serializer");
response.Message = "Sucess";
response.HSDStatus = HSDStatus.FAILED;
byte[] array = SaveAsync<HsdFilledMessage>(response);
UploadLog.Debug("~: Message to app
");
if (clientSocket.Connected)
{
try
{
UploadLog.Debug("~: Socket:
ClientSocket is connected");
int res =
clientSocket.Send(array);
UploadLog.Debug("~: Send result:
" + res);
}
catch (Exception ex)
{
UploadLog.Debug("~: Send method
failed" + ex.Message.ToString());
}
}
//Will receive another message for Registration file
upload. so wait for data.
clientSocket.Dispose();
}
}
}
}
else
{
UploadLog.Debug("~: ReceiveCallBack: IAsyncResult is received as
null");
}
}
catch (Exception ex)
{
UploadLog.Debug("~: ReceiveCallback Exception: " + ex.Message );
}
}
This is a Deserialize function, it will be convert and return
the specified type object from string
public T RestoreAsync<T>(string xml)
{
using (Stream stream = new MemoryStream())
{
byte[] data
= System.Text.Encoding.UTF8.GetBytes(xml);
stream.Write(data, 0,
data.Length);
stream.Position = 0;
DataContractSerializer deserializer = new DataContractSerializer(typeof(T));
return (T)deserializer.ReadObject(stream);
}
}
This is a serialize function, it will be convert and return the
byte from object
public static byte[] SaveAsync<T>(object content)
{
try
{
byte[] array;
using (MemoryStream memoryStream = new MemoryStream())
using (StreamReader reader = new StreamReader(memoryStream))
{
DataContractSerializer
serializer;
serializer = new DataContractSerializer(typeof(T));
serializer.WriteObject(memoryStream, content);
memoryStream.Position = 0;
array = new byte[memoryStream.Length];
memoryStream.Read(array, 0,
array.Length);
}
return array;
}
catch
{
throw;
}
}
Implementing and communicate Socket in Store Apps
Initialize port number
and IP address for communicate server socket listener. First Connect socket
service and write data in “OutputStream” for sending data from client to
server. The Server socket listener will be Deserialize stream from request
object and sent response stream to client service
private async void backButton_Click_1(object sender, RoutedEventArgs e)
{
try
{
StreamSocket clientSocket = new StreamSocket();
string port = "39529";
string host = "127.0.0.1";
await clientSocket.ConnectAsync(new Windows.Networking.HostName(host), port, SocketProtectionLevel.PlainSocket);
HsdFilledMessage message = new HsdFilledMessage();
byte[] inputByte = SaveAsync<HsdFilledMessage>(message);
DataWriter clientDataWriter = new DataWriter(clientSocket.OutputStream);
clientDataWriter.WriteBytes(inputByte);
await clientDataWriter.StoreAsync();
await clientDataWriter.FlushAsync();
string responseFromService = string.Empty;
var readBuf = new Windows.Storage.Streams.Buffer(10240000);
var readOp = await clientSocket.InputStream.ReadAsync(readBuf, 10240000, InputStreamOptions.Partial);
DataReader readPacket = DataReader.FromBuffer(readBuf);
uint buffLen = readPacket.UnconsumedBufferLength;
responseFromService =
readPacket.ReadString(buffLen);
var response = RestoreAsync<HsdFilledMessage>(responseFromService);
}
catch (Exception ex)
{
}
}
Download full source code here
No comments:
Post a Comment