Answered by:
[UWP][C#]TCP Socket server using IPEndPoint (UWP)

Question
-
Hi
I want to use an IPEndPoint in UWP to initial a server Socket.
Unfortunately all the document for Windows.Networking.Sockets are based on"StreamSocketListener" and using "ServiceName" or "HostName". Moreover, it seems Socket in Windows.Networking.Sockets doesn't have BeginAccept, BeginConnect, etc. method
I have wrote following codes but it did not work.
void Server_Start() { mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ipEndPoint = new IPEndPoint(IPAddress.Parse(ipAddress), Port_no); mySocket.NoDelay = true; mySocket.Bind(ipEndPoint); mySocket.Listen(5); mySocket.AcceptAsync(); }
would mind please help me to find proper example.
Best Regards
Reza
- Edited by Reza Neam Wednesday, April 19, 2017 8:19 AM
- Edited by Breeze Liu Thursday, April 20, 2017 6:28 AM add tag [UWP][C#]
Wednesday, April 19, 2017 8:04 AM
Answers
-
Thank you Breeze
Finally I found more flexible solution for local TCP/IP connection in windows Universal environment.
Definitely using Socket instead of StreamSocketListener and StreamSocket gives you more flexible, robust and stable solution.
Here is the possible solution
public static IPHostEntry ipHostInfo;
SocketAsyncEventArgs AcceptArg, RecieveArg, SendArg;
public static IPEndPoint ipEndPoint;
public static Socket server_socket;
public static Socket Client_Socket;void Start() { try { ipEndPoint = new IPEndPoint(ipAddress, PortNo)); server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); server_socket.NoDelay = true; server_socket.Bind(ipEndPoint); server_socket.Listen(5); AcceptArg = new SocketAsyncEventArgs(); AcceptArg.Completed += AcceptArg_Completed; server_socket.AcceptAsync(AcceptArg); } catch (Exception excp) { Debug.WriteLine(excp.Message); } } private void AcceptArg_Completed(object sender, SocketAsyncEventArgs e) { Client_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Client_Socket = e.AcceptSocket; Debug.WriteLine("EndPoint " + Client_Socket.RemoteEndPoint ); RecieveArg = new SocketAsyncEventArgs(); RecieveArg.UserToken = server_socket; RecieveArg.RemoteEndPoint = Client_Socket.RemoteEndPoint; RecieveArg.SetBuffer(buffer, 0, buffer.Length); RecieveArg.Completed += RecieveArg_Completed; Client_Socket.ReceiveAsync(RecieveArg); } private void RecieveArg_Completed(object sender, SocketAsyncEventArgs e) { byte[] recBuf = new byte[e.BytesTransferred]; Array.Copy(buffer, recBuf, e.BytesTransferred); string ReceivedText = Encoding.ASCII.GetString(recBuf); Client_Socket.ReceiveAsync(RecieveArg); } void SendText(string text ) { byte[] data = Encoding.ASCII.GetBytes(text); Client_Socket.Send(data); }
Best Regards
Reza
- Proposed as answer by Breeze Liu Wednesday, May 10, 2017 12:47 AM
- Marked as answer by Reza Neam Tuesday, August 15, 2017 3:29 PM
Tuesday, May 9, 2017 1:37 PM
All replies
-
Hi Reza Naeema,
Welcome to the Developing Universal Windows apps forum! Please utilize tagging when posting to this forum, thanks!
>>I have wrote following codes but it did not work.
What is the mean that it did not work? Whether it cause an exception? If that, could you share the info? In my test, the code can work, but mySocket.AcceptAsync() need an argument such as AcceptAsync(SocketAsyncEventArgs).
By the way, what function do you want to implement?
Best regards,
Breeze
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.Thursday, April 20, 2017 8:00 AM -
Hi Breeze
Thank you for your reply.
I mean, the socket was bound to the specified IP/Port but it didn't accept any client request.
AcceptAsync has 3 override functions which just one of them accept SocketAsyncEventArgs argument. I couldn't find comprehensive document for UWP.
I would like to establish TCP/IP communication between Raspberry Pi (server) and PC (client).
By the way, the only document I find is in here, which was not useful at all.
https://docs.microsoft.com/en-us/dotnet/api/system.net.sockets.tcplistener?view=netcore-1.1
Best Regards
Reza
- Edited by Reza Neam Thursday, April 20, 2017 12:48 PM
Thursday, April 20, 2017 10:09 AM -
Hi Reza Naeema,
In uwp, we implement socket by creating a StreamSocketListener object as a server to start listening for incoming TCP connections and creating a StreamSocket object as a client to establish a connection to the remote server, send a request, and receive a response. More details, see Sockets and sample.
If you want to use the .Net api to implement the socket, you can refer to Socket Code Examples.
Best regards,
Breeze
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.Friday, April 21, 2017 5:45 AM -
Hi Breeze
Thanks for replay.
I tried to use the available example codes.
I success to implement part of the StreamSocketListener and I still have some issue with tcp packet!
for example when sever sends 42 bytes, surprisingly client receives 46 bytes packet.
and after a few packets I received following exception
Exception thrown: 'System.ObjectDisposedException' in SM7UWP.exe Send failed with error: The object has been closed. (Exception from HRESULT: 0x80000013)
Here is my UWP (server) code
async private void StartListener(LocalHostItem selectedLocalHost) { listener = new StreamSocketListener(); listener.ConnectionReceived += Listener_ConnectionReceived; listener.Control.KeepAlive = false; await listener.BindEndpointAsync(selectedLocalHost.LocalHost, PortNoTXTB.Text); } private void Listener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args) { ClientSocket = args.Socket; } async void WriteData(float[] data) { if (ClientSocke != null) { string text = String.Format("{0},{1},{2},{3}", data[1], data[2], data[3], data[0]); DataWriter writer = new DataWriter(ClientSocke.OutputStream); writer.WriteUInt32(writer.MeasureString(text)); byte[] myData = Encoding.ASCII.GetBytes(text); writer.WriteBytes(myData); try { await writer.StoreAsync(); Debug.WriteLine( text + " sent successfully. Len: " + myData.Length); } catch (Exception exception) { Debug.WriteLine("Send failed with error: " + exception.Message); } }
and on the client side I have following code
public Socket mySocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); public IPHostEntry HostInfo; public IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("172.26.24.22"), 20212); public const int BUFFER_SIZE = 2048; public readonly byte[] buffer = new byte[BUFFER_SIZE]; mySocket.BeginConnect(ipEndPoint, ConnectCallBack, mySocket); void ConnectCallBack(IAsyncResult ar) { try { mySocket.EndConnect(ar); mySocket.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, mySocket); Connected = true; Debug.Log("Connected to Server"); } catch (SocketException) { Connected = false; Debug.Log("Connection Failed"); } } void ReceiveCallback(IAsyncResult AR) { Socket current = (Socket)AR.AsyncState; int received; received = current.EndReceive(AR); byte[] recBuf = new byte[received]; Array.Copy(buffer, recBuf, received); ASCIIEncoding ascii = new ASCIIEncoding(); string ReceivedText = ascii.GetString(recBuf); try { Debug.Log(ReceivedText + " len " + received); string[] Qs = ReceivedText.Split(','); if (Qs.Length == 4) Q.Set(float.Parse(Qs[0]), float.Parse(Qs[1]), float.Parse(Qs[2]), float.Parse(Qs[3])); } catch (SocketException e) { current.Close(); Connected = false; Debug.Log(e.Message); } current.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current); }
I am really confused why I receive tcp packet with two different length!
Regards
Reza
Tuesday, April 25, 2017 1:25 PM -
Hi Reza Naeema,
I try to recover your project to test, but I am failed, could your provide a simple entire sample for us to reproduce this issue?
Best regards,
Breeze
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.Wednesday, April 26, 2017 7:19 AM -
Thank you Breeze
Finally I found more flexible solution for local TCP/IP connection in windows Universal environment.
Definitely using Socket instead of StreamSocketListener and StreamSocket gives you more flexible, robust and stable solution.
Here is the possible solution
public static IPHostEntry ipHostInfo;
SocketAsyncEventArgs AcceptArg, RecieveArg, SendArg;
public static IPEndPoint ipEndPoint;
public static Socket server_socket;
public static Socket Client_Socket;void Start() { try { ipEndPoint = new IPEndPoint(ipAddress, PortNo)); server_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); server_socket.NoDelay = true; server_socket.Bind(ipEndPoint); server_socket.Listen(5); AcceptArg = new SocketAsyncEventArgs(); AcceptArg.Completed += AcceptArg_Completed; server_socket.AcceptAsync(AcceptArg); } catch (Exception excp) { Debug.WriteLine(excp.Message); } } private void AcceptArg_Completed(object sender, SocketAsyncEventArgs e) { Client_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Client_Socket = e.AcceptSocket; Debug.WriteLine("EndPoint " + Client_Socket.RemoteEndPoint ); RecieveArg = new SocketAsyncEventArgs(); RecieveArg.UserToken = server_socket; RecieveArg.RemoteEndPoint = Client_Socket.RemoteEndPoint; RecieveArg.SetBuffer(buffer, 0, buffer.Length); RecieveArg.Completed += RecieveArg_Completed; Client_Socket.ReceiveAsync(RecieveArg); } private void RecieveArg_Completed(object sender, SocketAsyncEventArgs e) { byte[] recBuf = new byte[e.BytesTransferred]; Array.Copy(buffer, recBuf, e.BytesTransferred); string ReceivedText = Encoding.ASCII.GetString(recBuf); Client_Socket.ReceiveAsync(RecieveArg); } void SendText(string text ) { byte[] data = Encoding.ASCII.GetBytes(text); Client_Socket.Send(data); }
Best Regards
Reza
- Proposed as answer by Breeze Liu Wednesday, May 10, 2017 12:47 AM
- Marked as answer by Reza Neam Tuesday, August 15, 2017 3:29 PM
Tuesday, May 9, 2017 1:37 PM -
Hi Reza Naeema,
Thanks for sharing your solution, I am glad to hear that you have resolved this issue. Besides, I also learn more from it, thank you very much.
Best regards,
Breeze
MSDN Community Support
Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.Wednesday, May 10, 2017 12:55 AM