{"id":589,"date":"2011-05-17T11:42:35","date_gmt":"2011-05-17T11:42:35","guid":{"rendered":"https:\/\/ibex.tech\/visualcpp\/?p=589"},"modified":"2022-02-17T06:24:04","modified_gmt":"2022-02-17T06:24:04","slug":"udp-server","status":"publish","type":"post","link":"https:\/\/ibex.tech\/visualcpp\/tcp-ip\/udp-server","title":{"rendered":"UDP Server"},"content":{"rendered":"<h4>In Your .h File<\/h4>\n<pre><code>\r\n#define\tRECEIVE_BUFFER_SIZE\t\t\t\t\t\t1500\r\n\r\nprivate: Socket ^serverSocket;\r\n\r\n\t\/\/-------------------------------------\r\n\t\/\/----- CLASS FOR RECEIVE SOCKETS -----\r\n\t\/\/-------------------------------------\r\n\tref class StateObject\r\n\t{\r\n\tpublic:\r\n\t\tproperty int bufSize;\r\n\t\tproperty Socket ^workSocket;\r\n\t\tproperty array&lt;unsigned char&gt;^ message;\r\n\r\n\t\tStateObject(Socket^ sock, int bufsize)\r\n\t\t{\r\n\t\t\tworkSocket = sock;\r\n\t\t\tbufSize = bufsize;\r\n\t\t\tmessage = gcnew array&lt;unsigned char&gt;(bufsize);\r\n\t\t}\r\n\t};\r\n<\/code><\/pre>\n<h4>Create Socket<\/h4>\n<pre><code>\r\n\r\n\t\/\/----- SETUP UDP ASYNCHRONOUS RECEIVE -----\r\n\ttry\r\n\t{\r\n\t\t\/\/----- CREATE UDP SOCKET AND BIND TO LOCAL PORT -----\r\n\t\tserverSocket = gcnew Socket(AddressFamily::InterNetwork, SocketType::Dgram, ProtocolType::Udp);\r\n\t\tIPEndPoint ^ipEndPoint = gcnew IPEndPoint(IPAddress::Any, LOCAL_UDP_SOCKET);\t\t\/\/Assign the any IP of the machine and listen on port number\r\n\t\tserverSocket-&gt;Bind(ipEndPoint);\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\/\/Bind required if not sending data (sending does bind for you)\r\n\r\n\t\t\/\/----- CREATE ASYNCHRONOUS RECEIVE HANDLER -----<\/code>myClassName<code>\r\n\t\tIPEndPoint ^ipeSender1 = gcnew IPEndPoint(IPAddress::Any, 0);\r\n\t\tEndPoint ^epSender1 = (EndPoint^)(ipeSender1);\t\t\t\t\t\t\/\/The epSender identifies the incoming clients\r\n\t\tStateObject ^so1 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);\r\n\r\n\t\t\/\/Start reciving data using BeginReceiveFrom\r\n\t\t\/\/(Use BeginReceiveFrom not BeginReceive so we can determin the sender when we receive a packet - only way when using UDP.  If you don't care who the sender is you could use BeginReceive if you wanted, but no particular reason you need to)\r\n\t\tserverSocket-&gt;BeginReceiveFrom (so1-&gt;message, 0, so1-&gt;bufSize, \/\/Byte array to store received data, offset into the buffer to start sotring the data, number of bytes to receive,\r\n\t\t\t\t\t\t\t\t\t\tSocketFlags::None, epSender1,\t\t \/\/bitwise combination of the SocketFlags values, EndPoint that represents the source of the data.\r\n\t\t\t\t\t\t\t\t\t\tgcnew AsyncCallback(this, &amp;myClassName::ReceiveCallback), so1);\t\/\/AsyncCallback delegate, object containing state information for this request\r\n\r\n\t\t\/\/UDP will also drop packets upon receipt if, even momentarily, BeginReceiveFrom is not active on the socket.\r\n\t\t\/\/There is a short time between acceptance of a packet and calling another BeginReceiveFrom. Even if this call were the first one in MessageReceivedCallback, there's a\r\n\t\t\/\/still short period when the app isn't listening. A simple solution is to activate several instances of BeginReceiveFrom, each with a separate buffer to hold received\r\n\t\t\/\/packets.\r\n\r\n\t\t\/\/CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER\r\n\t\tIPEndPoint^ ipeSender2 = gcnew IPEndPoint(IPAddress::Any, 0);\r\n\t\tEndPoint^ epSender2 = (EndPoint^)(ipeSender2);\r\n\t\tStateObject^ so2 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);\r\n\t\tserverSocket-&gt;BeginReceiveFrom (so2-&gt;message, 0, so2-&gt;bufSize,\r\n\t\t\t\t\t\t\t\t\t\tSocketFlags::None, epSender2,\r\n\t\t\t\t\t\t\t\t\t\tgcnew AsyncCallback(this, &amp;myClassName::ReceiveCallback), so2);\r\n\r\n\t\t\/\/CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER\r\n\t\tIPEndPoint^ ipeSender3 = gcnew IPEndPoint(IPAddress::Any, 0);\r\n\t\tEndPoint^ epSender3 = (EndPoint^)(ipeSender3);\r\n\t\tStateObject^ so3 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);\r\n\t\tserverSocket-&gt;BeginReceiveFrom (so3-&gt;message, 0, so3-&gt;bufSize,\r\n\t\t\t\t\t\t\t\t\t\tSocketFlags::None, epSender3,\r\n\t\t\t\t\t\t\t\t\t\tgcnew AsyncCallback(this, &amp;myClassName::ReceiveCallback), so3);\r\n\r\n\t\t\/\/CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER\r\n\t\tIPEndPoint^ ipeSender4 = gcnew IPEndPoint(IPAddress::Any, 0);\r\n\t\tEndPoint^ epSender4 = (EndPoint^)(ipeSender4);\r\n\t\tStateObject^ so4 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);\r\n\t\tserverSocket-&gt;BeginReceiveFrom (so4-&gt;message, 0, so4-&gt;bufSize,\r\n\t\t\t\t\t\t\t\t\t\tSocketFlags::None, epSender4,\r\n\t\t\t\t\t\t\t\t\t\tgcnew AsyncCallback(this, &amp;myClassName::ReceiveCallback), so4);\r\n\r\n\t\t\/\/CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER\r\n\t\tIPEndPoint^ ipeSender5 = gcnew IPEndPoint(IPAddress::Any, 0);\r\n\t\tEndPoint^ epSender5 = (EndPoint^)(ipeSender5);\r\n\t\tStateObject^ so5 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);\r\n\t\tserverSocket-&gt;BeginReceiveFrom (so5-&gt;message, 0, so5-&gt;bufSize,\r\n\t\t\t\t\t\t\t\t\t\tSocketFlags::None, epSender5,\r\n\t\t\t\t\t\t\t\t\t\tgcnew AsyncCallback(this, &amp;myClassName::ReceiveCallback), so5);\r\n\r\n\t\t\/\/CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER\r\n\t\tIPEndPoint^ ipeSender6 = gcnew IPEndPoint(IPAddress::Any, 0);\r\n\t\tEndPoint^ epSender6 = (EndPoint^)(ipeSender6);\r\n\t\tStateObject^ so6 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);\r\n\t\tserverSocket-&gt;BeginReceiveFrom (so6-&gt;message, 0, so6-&gt;bufSize,\r\n\t\t\t\t\t\t\t\t\t\tSocketFlags::None, epSender6,\r\n\t\t\t\t\t\t\t\t\t\tgcnew AsyncCallback(this, &amp;myClassName::ReceiveCallback), so6);\r\n\r\n\t\t\/\/CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER\r\n\t\tIPEndPoint^ ipeSender7 = gcnew IPEndPoint(IPAddress::Any, 0);\r\n\t\tEndPoint^ epSender7 = (EndPoint^)(ipeSender7);\r\n\t\tStateObject^ so7 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);\r\n\t\tserverSocket-&gt;BeginReceiveFrom (so7-&gt;message, 0, so7-&gt;bufSize,\r\n\t\t\t\t\t\t\t\t\t\tSocketFlags::None, epSender7,\r\n\t\t\t\t\t\t\t\t\t\tgcnew AsyncCallback(this, &amp;myClassName::ReceiveCallback), so7);\r\n\r\n\t\t\/\/CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER\r\n\t\tIPEndPoint^ ipeSender8 = gcnew IPEndPoint(IPAddress::Any, 0);\r\n\t\tEndPoint^ epSender8 = (EndPoint^)(ipeSender8);\r\n\t\tStateObject^ so8 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);\r\n\t\tserverSocket-&gt;BeginReceiveFrom (so8-&gt;message, 0, so8-&gt;bufSize,\r\n\t\t\t\t\t\t\t\t\t\tSocketFlags::None, epSender8,\r\n\t\t\t\t\t\t\t\t\t\tgcnew AsyncCallback(this, &amp;myClassName::ReceiveCallback), so8);\r\n\r\n\t}\r\n\tcatch (Exception ^e)\r\n\t{\r\n\t}\r\n<\/code><\/pre>\n<h4>Receive Handler<\/h4>\n<pre><code>\r\n\t\/\/*********************************\r\n\t\/\/*********************************\r\n\t\/\/********** UDP RECEIVE **********\r\n\t\/\/*********************************\r\n\t\/\/*********************************\r\n\tvoid myClassName::ReceiveCallback(System::IAsyncResult^ iar)\r\n\t{\r\n\t\tint byteId;\r\n\t\tUInt16 OpCode;\r\n\t\tString ^RxFromIp;\r\n\t\tUInt16 RxFromPort;\r\n\t\tint ReTries;\r\n\r\n\t\tStateObject^ so = (StateObject^)iar-&gt;AsyncState;\r\n\t\tSocket^ client = so-&gt;workSocket;\r\n\r\n\t\t\/\/-----------------------------------\r\n\t\t\/\/----- PROCESS RECEIVED PACKET -----\r\n\t\t\/\/-----------------------------------\r\n\t\ttry\r\n\t\t{\r\n\t\t\t\/\/Create a temporary EndPoint to pass to EndReceiveFrom (we have to do this to be able to get the RemoteEndPoint information - only way when using UDP)\r\n\t\t\tIPEndPoint^ sender = gcnew IPEndPoint( IPAddress::Any,0 );\r\n\t\t\tEndPoint^ tempRemoteEP = safe_cast&lt;EndPoint^&gt;(sender);\r\n\r\n\t\t\tint rcv;\r\n\t\t\tif ((rcv = client-&gt;EndReceiveFrom(iar, tempRemoteEP )) &gt; 0)\t\/\/Complete BeginReceive operation and get the message\r\n\t\t\t{\r\n\t\t\t\tbyteId = 0;\r\n\t\t\t\tif (\r\n\t\t\t\t(so-&gt;message[byteId++] == 'H') &amp;&amp;\r\n\t\t\t\t(so-&gt;message[byteId++] == 'e') &amp;&amp;\r\n\t\t\t\t(so-&gt;message[byteId++] == 'l') &amp;&amp;\r\n\t\t\t\t(so-&gt;message[byteId++] == 'l') &amp;&amp;\r\n\t\t\t\t(so-&gt;message[byteId++] == 'o')\r\n\t\t\t\t)\r\n\t\t\t\t{\r\n\t\t\t\t\t\/\/------------------------\r\n\t\t\t\t\t\/\/----- VALID PACKET -----\r\n\t\t\t\t\t\/\/------------------------\r\n\r\n\t\t\t\t\t\/\/Get OpCode\r\n\t\t\t\t\tOpCode = Convert::ToInt32(so-&gt;message[byteId++]) &lt;&lt; 8;\r\n\t\t\t\t\tOpCode |= Convert::ToInt32(so-&gt;message[byteId++]);\r\n\r\n\t\t\t\t\t\/\/----- GET SENDERS IP ADDRESS -----\r\n\t\t\t\t\tSocketAddress^ remoteDeviceAddress = tempRemoteEP-&gt;Serialize();\r\n\r\n\t\t\t\t\tif (remoteDeviceAddress-&gt;Family == AddressFamily::InterNetwork)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\/\/IPv4 Address\r\n\t\t\t\t\t\tRxFromPort = Convert::ToUInt16(remoteDeviceAddress[2]) &lt;&lt; 8;\t\/\/Port number is in bytes 2:3\r\n\t\t\t\t\t\tRxFromPort |= Convert::ToUInt16(remoteDeviceAddress[3]);\r\n\t\t\t\t\t\tRxFromIp = remoteDeviceAddress[4] + \".\" + remoteDeviceAddress[5] + \".\" + remoteDeviceAddress[6] + \".\" + remoteDeviceAddress[7]; \/\/IP Address in bytes 4:7\r\n\t\t\t\t\t}\r\n\t\t\t\t\t\/\/else if (remoteDeviceAddress-&gt;Family == AddressFamily::InterNetworkV6)\r\n\t\t\t\t\t\/\/{\r\n\t\t\t\t\t\/\/\t\/\/IPv6 Address\r\n\t\t\t\t\t\/\/}\r\n\t\t\t\t\telse\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\tRxFromIp = \"0.0.0.0\";\r\n\t\t\t\t\t\tOpCode = 0;\t\t\/\/Dump the packet\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tswitch (OpCode)\r\n\t\t\t\t\t{\r\n\t\t\t\t\tcase 0x1234:\r\n\t\t\t\t\t\t\/\/-----------------------\r\n\t\t\t\t\t\t\/\/-----------------------\r\n\t\t\t\t\t\t\/\/----- OPCODE 1234 -----\r\n\t\t\t\t\t\t\/\/-----------------------\r\n\t\t\t\t\t\t\/\/-----------------------\r\n\r\n\t\t\t\t\t\tSomeVariable = Convert::ToInt32(so-&gt;message[byteId++]) &lt;&lt; 8;\r\n\t\t\t\t\t\tSomeVariable |= Convert::ToInt32(so-&gt;message[byteId++]);\r\n\r\n\t\t\t\t\t\tSomeString = Convert::ToString(so-&gt;message[byteId++]) + \".\";\r\n\t\t\t\t\t\tSomeString += Convert::ToString(so-&gt;message[byteId++]) + \".\";\r\n\t\t\t\t\t\tSomeString += Convert::ToString(so-&gt;message[byteId++]) + \".\";\r\n\t\t\t\t\t\tSomeString += Convert::ToString(so-&gt;message[byteId++]);\r\n\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t} \/\/switch (OpCode)\r\n\r\n\t\t\t\t}\r\n\r\n\t\t\t}\r\n\t\t}\r\n\t\tcatch (Exception ^e)\r\n\t\t{\r\n\t\t}\r\n\t\tfinally\r\n\t\t{\r\n\t\t\t\/\/----------------------------------\r\n\t\t\t\/\/----- SETUP FOR NEXT RECEIVE -----\r\n\t\t\t\/\/----------------------------------\r\n\t\t\tReTries = 50;\t\t\/\/Limit the while loop just in case\r\n\t\t\twhile (ReTries)\t\t\/\/We use a while loop as BeginReceiveFrom can occasionally cause a SocketException error when there is lots of receive activity.  Without this the BeginReceiveFrom is lost causing no receive anymore once they are all used up.\r\n\t\t\t{\r\n\t\t\t\tReTries--;\r\n\t\t\t\ttry\r\n\t\t\t\t{\r\n\t\t\t\t\t\/\/----- CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER TO REPLACE THIS ONE JUST USED -----\r\n\t\t\t\t\tIPEndPoint^ ipeSender = gcnew IPEndPoint(IPAddress::Any, 0);\r\n\t\t\t\t\tEndPoint^ epSender = (EndPoint^)(ipeSender);\t\t\t\t\t\t\/\/The epSender identifies the incoming clients\r\n\t\t\t\t\tso = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);\r\n\r\n\t\t\t\t\tserverSocket-&gt;BeginReceiveFrom (so-&gt;message, 0, so-&gt;bufSize, \/\/Byte array to store received data, offset into the buffer to start sotring the data, number of bytes to receive,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\tSocketFlags::None, epSender,\t\t \/\/bitwise combination of the SocketFlags values, EndPoint that represents the source of the data.\r\n\t\t\t\t\t\t\t\t\t\t\t\t\tgcnew AsyncCallback(this, &DibbaReaders::ReceiveCallback), so);\t\/\/AsyncCallback delegate, object containing state information for this request\r\n\t\t\t\t\tReTries = 0;\r\n\t\t\t\t}\r\n\t\t\t\tcatch (Exception ^)\r\n\t\t\t\t{\t\t\t\r\n\t\t\t\t}\r\n\t\t\t}\t\r\n\t\t}\r\n\r\n\t}\r\n<\/code><\/pre>\n<h4>Transmit Packet From Server Socket<\/h4>\n<pre><code>\r\n\t\tIPAddress ^address;\r\n\t\tint byteId;\r\n\t\tarray&lt;Byte&gt;^sendBytes = gcnew array&lt;Byte&gt;(1500);\r\n\r\n\t\ttry\r\n\t\t{\r\n\t\t\tif (!IPAddress::TryParse(DestIpAddressString, address))\r\n\t\t\t{\r\n\t\t\t\t\/\/Invalid IP Address\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tbyteId = 0;\r\n\r\n\t\t\tsendBytes[byteId++] = ;\r\n\t\t\t...\r\n\t\t\tsendBytes[byteId++] = ;\r\n\r\n\t\t\t\/\/Transmit Packet\r\n\t\t\tIPEndPoint ^Remote = gcnew IPEndPoint(address, REMOTE_UDP_SOCKET);\r\n\t\t\tserverSocket-&gt;SendTo(sendBytes, byteId, System::Net::Sockets::SocketFlags::None, Remote);\r\n\t\t}\r\n\t\tcatch (Exception ^)\r\n\t\t{\r\n\t\t}\r\n<\/code><\/pre>\n<h4>Transmit Packet From Server Socket With Packet Sent Callback<\/h4>\n<pre><code>\r\n\r\n\tIPAddress ^address;\r\n\tint byteId;\r\n\tarray&lt;Byte&gt;^sendBytes = gcnew array&lt;Byte&gt;(1500);\r\n\r\n\ttry\r\n\t{\r\n\t\tif (!IPAddress::TryParse(DestIpAddressString, address))\r\n\t\t{\r\n\t\t\t\/\/Invalid IP Address\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tbyteId = 0;\r\n\r\n\t\tsendBytes[byteId++] = ;\r\n\t\t...\r\n\t\tsendBytes[byteId++] = ;\r\n\r\n\t\t\/\/Transmit Packet\r\n\t\tIPEndPoint ^Remote = gcnew IPEndPoint(address, REMOTE_UDP_SOCKET);\r\n\t\tserverSocket-&gt;BeginSendTo(sendBytes, 0, byteId, System::Net::Sockets::SocketFlags::None, Remote, gcnew AsyncCallback(this, &amp;myClassName::OurSendCallback), serverSocket);\r\n\t\twhile (WaitingTxToComplete)\r\n\t\t\tThreading::Thread::Sleep(20);\t\/\/(Needed or deployment release version running from .exe will crash)\r\n\r\n\t}\r\n\tcatch (Exception ^)\r\n\t{\r\n\t}\r\n\r\n\t\/\/*************************************\r\n\t\/\/*************************************\r\n\t\/\/********** UDP TX CALLBACK **********\r\n\t\/\/*************************************\r\n\t\/\/*************************************\r\n\tvoid myClassName::OurSendCallback(IAsyncResult^ asyncResult)\r\n    {\r\n\t\tserverSocket-&gt;EndSend(asyncResult);\r\n\t\tWaitingTxToComplete = false;\r\n    }\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In Your .h File #define RECEIVE_BUFFER_SIZE 1500 private: Socket ^serverSocket; \/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- \/\/&#8212;&#8211; CLASS FOR RECEIVE SOCKETS &#8212;&#8211; \/\/&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;- ref class StateObject { public: property int bufSize; property Socket ^workSocket; property array&lt;unsigned char&gt;^ message; StateObject(Socket^ sock, int bufsize) { workSocket = sock; bufSize = bufsize; message = gcnew array&lt;unsigned char&gt;(bufsize); } }; Create Socket \/\/&#8212;&#8211; SETUP [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":["post-589","post","type-post","status-publish","format-standard","hentry","category-tcp-ip"],"_links":{"self":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts\/589","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/comments?post=589"}],"version-history":[{"count":7,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts\/589\/revisions"}],"predecessor-version":[{"id":1047,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/posts\/589\/revisions\/1047"}],"wp:attachment":[{"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/media?parent=589"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/categories?post=589"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ibex.tech\/visualcpp\/wp-json\/wp\/v2\/tags?post=589"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}