In Your .h File


#define	RECEIVE_BUFFER_SIZE						1500

private: Socket ^serverSocket;

	//-------------------------------------
	//----- CLASS FOR RECEIVE SOCKETS -----
	//-------------------------------------
	ref class StateObject
	{
	public:
		property int bufSize;
		property Socket ^workSocket;
		property array<unsigned char>^ message;

		StateObject(Socket^ sock, int bufsize)
		{
			workSocket = sock;
			bufSize = bufsize;
			message = gcnew array<unsigned char>(bufsize);
		}
	};

Create Socket



	//----- SETUP UDP ASYNCHRONOUS RECEIVE -----
	try
	{
		//----- CREATE UDP SOCKET AND BIND TO LOCAL PORT -----
		serverSocket = gcnew Socket(AddressFamily::InterNetwork, SocketType::Dgram, ProtocolType::Udp);
		IPEndPoint ^ipEndPoint = gcnew IPEndPoint(IPAddress::Any, LOCAL_UDP_SOCKET);		//Assign the any IP of the machine and listen on port number
		serverSocket->Bind(ipEndPoint);															//Bind required if not sending data (sending does bind for you)

		//----- CREATE ASYNCHRONOUS RECEIVE HANDLER -----myClassName
		IPEndPoint ^ipeSender1 = gcnew IPEndPoint(IPAddress::Any, 0);
		EndPoint ^epSender1 = (EndPoint^)(ipeSender1);						//The epSender identifies the incoming clients
		StateObject ^so1 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);

		//Start reciving data using BeginReceiveFrom
		//(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)
		serverSocket->BeginReceiveFrom (so1->message, 0, so1->bufSize, //Byte array to store received data, offset into the buffer to start sotring the data, number of bytes to receive,
										SocketFlags::None, epSender1,		 //bitwise combination of the SocketFlags values, EndPoint that represents the source of the data.
										gcnew AsyncCallback(this, &myClassName::ReceiveCallback), so1);	//AsyncCallback delegate, object containing state information for this request

		//UDP will also drop packets upon receipt if, even momentarily, BeginReceiveFrom is not active on the socket.
		//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
		//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
		//packets.

		//CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER
		IPEndPoint^ ipeSender2 = gcnew IPEndPoint(IPAddress::Any, 0);
		EndPoint^ epSender2 = (EndPoint^)(ipeSender2);
		StateObject^ so2 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);
		serverSocket->BeginReceiveFrom (so2->message, 0, so2->bufSize,
										SocketFlags::None, epSender2,
										gcnew AsyncCallback(this, &myClassName::ReceiveCallback), so2);

		//CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER
		IPEndPoint^ ipeSender3 = gcnew IPEndPoint(IPAddress::Any, 0);
		EndPoint^ epSender3 = (EndPoint^)(ipeSender3);
		StateObject^ so3 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);
		serverSocket->BeginReceiveFrom (so3->message, 0, so3->bufSize,
										SocketFlags::None, epSender3,
										gcnew AsyncCallback(this, &myClassName::ReceiveCallback), so3);

		//CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER
		IPEndPoint^ ipeSender4 = gcnew IPEndPoint(IPAddress::Any, 0);
		EndPoint^ epSender4 = (EndPoint^)(ipeSender4);
		StateObject^ so4 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);
		serverSocket->BeginReceiveFrom (so4->message, 0, so4->bufSize,
										SocketFlags::None, epSender4,
										gcnew AsyncCallback(this, &myClassName::ReceiveCallback), so4);

		//CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER
		IPEndPoint^ ipeSender5 = gcnew IPEndPoint(IPAddress::Any, 0);
		EndPoint^ epSender5 = (EndPoint^)(ipeSender5);
		StateObject^ so5 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);
		serverSocket->BeginReceiveFrom (so5->message, 0, so5->bufSize,
										SocketFlags::None, epSender5,
										gcnew AsyncCallback(this, &myClassName::ReceiveCallback), so5);

		//CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER
		IPEndPoint^ ipeSender6 = gcnew IPEndPoint(IPAddress::Any, 0);
		EndPoint^ epSender6 = (EndPoint^)(ipeSender6);
		StateObject^ so6 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);
		serverSocket->BeginReceiveFrom (so6->message, 0, so6->bufSize,
										SocketFlags::None, epSender6,
										gcnew AsyncCallback(this, &myClassName::ReceiveCallback), so6);

		//CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER
		IPEndPoint^ ipeSender7 = gcnew IPEndPoint(IPAddress::Any, 0);
		EndPoint^ epSender7 = (EndPoint^)(ipeSender7);
		StateObject^ so7 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);
		serverSocket->BeginReceiveFrom (so7->message, 0, so7->bufSize,
										SocketFlags::None, epSender7,
										gcnew AsyncCallback(this, &myClassName::ReceiveCallback), so7);

		//CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER
		IPEndPoint^ ipeSender8 = gcnew IPEndPoint(IPAddress::Any, 0);
		EndPoint^ epSender8 = (EndPoint^)(ipeSender8);
		StateObject^ so8 = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);
		serverSocket->BeginReceiveFrom (so8->message, 0, so8->bufSize,
										SocketFlags::None, epSender8,
										gcnew AsyncCallback(this, &myClassName::ReceiveCallback), so8);

	}
	catch (Exception ^e)
	{
	}

Receive Handler


	//*********************************
	//*********************************
	//********** UDP RECEIVE **********
	//*********************************
	//*********************************
	void myClassName::ReceiveCallback(System::IAsyncResult^ iar)
	{
		int byteId;
		UInt16 OpCode;
		String ^RxFromIp;
		UInt16 RxFromPort;
		int ReTries;

		StateObject^ so = (StateObject^)iar->AsyncState;
		Socket^ client = so->workSocket;

		//-----------------------------------
		//----- PROCESS RECEIVED PACKET -----
		//-----------------------------------
		try
		{
			//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)
			IPEndPoint^ sender = gcnew IPEndPoint( IPAddress::Any,0 );
			EndPoint^ tempRemoteEP = safe_cast<EndPoint^>(sender);

			int rcv;
			if ((rcv = client->EndReceiveFrom(iar, tempRemoteEP )) > 0)	//Complete BeginReceive operation and get the message
			{
				byteId = 0;
				if (
				(so->message[byteId++] == 'H') &&
				(so->message[byteId++] == 'e') &&
				(so->message[byteId++] == 'l') &&
				(so->message[byteId++] == 'l') &&
				(so->message[byteId++] == 'o')
				)
				{
					//------------------------
					//----- VALID PACKET -----
					//------------------------

					//Get OpCode
					OpCode = Convert::ToInt32(so->message[byteId++]) << 8;
					OpCode |= Convert::ToInt32(so->message[byteId++]);

					//----- GET SENDERS IP ADDRESS -----
					SocketAddress^ remoteDeviceAddress = tempRemoteEP->Serialize();

					if (remoteDeviceAddress->Family == AddressFamily::InterNetwork)
					{
						//IPv4 Address
						RxFromPort = Convert::ToUInt16(remoteDeviceAddress[2]) << 8;	//Port number is in bytes 2:3
						RxFromPort |= Convert::ToUInt16(remoteDeviceAddress[3]);
						RxFromIp = remoteDeviceAddress[4] + "." + remoteDeviceAddress[5] + "." + remoteDeviceAddress[6] + "." + remoteDeviceAddress[7]; //IP Address in bytes 4:7
					}
					//else if (remoteDeviceAddress->Family == AddressFamily::InterNetworkV6)
					//{
					//	//IPv6 Address
					//}
					else
					{
						RxFromIp = "0.0.0.0";
						OpCode = 0;		//Dump the packet
					}

					switch (OpCode)
					{
					case 0x1234:
						//-----------------------
						//-----------------------
						//----- OPCODE 1234 -----
						//-----------------------
						//-----------------------

						SomeVariable = Convert::ToInt32(so->message[byteId++]) << 8;
						SomeVariable |= Convert::ToInt32(so->message[byteId++]);

						SomeString = Convert::ToString(so->message[byteId++]) + ".";
						SomeString += Convert::ToString(so->message[byteId++]) + ".";
						SomeString += Convert::ToString(so->message[byteId++]) + ".";
						SomeString += Convert::ToString(so->message[byteId++]);

						break;

					} //switch (OpCode)

				}

			}
		}
		catch (Exception ^e)
		{
		}
		finally
		{
			//----------------------------------
			//----- SETUP FOR NEXT RECEIVE -----
			//----------------------------------
			ReTries = 50;		//Limit the while loop just in case
			while (ReTries)		//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.
			{
				ReTries--;
				try
				{
					//----- CREATE ANOTHER ASYNCHRONOUS RECEIVE HANDLER TO REPLACE THIS ONE JUST USED -----
					IPEndPoint^ ipeSender = gcnew IPEndPoint(IPAddress::Any, 0);
					EndPoint^ epSender = (EndPoint^)(ipeSender);						//The epSender identifies the incoming clients
					so = gcnew StateObject(serverSocket, RECEIVE_BUFFER_SIZE);

					serverSocket->BeginReceiveFrom (so->message, 0, so->bufSize, //Byte array to store received data, offset into the buffer to start sotring the data, number of bytes to receive,
													SocketFlags::None, epSender,		 //bitwise combination of the SocketFlags values, EndPoint that represents the source of the data.
													gcnew AsyncCallback(this, &DibbaReaders::ReceiveCallback), so);	//AsyncCallback delegate, object containing state information for this request
					ReTries = 0;
				}
				catch (Exception ^)
				{			
				}
			}	
		}

	}

Transmit Packet From Server Socket


		IPAddress ^address;
		int byteId;
		array<Byte>^sendBytes = gcnew array<Byte>(1500);

		try
		{
			if (!IPAddress::TryParse(DestIpAddressString, address))
			{
				//Invalid IP Address
				return;
			}
			byteId = 0;

			sendBytes[byteId++] = ;
			...
			sendBytes[byteId++] = ;

			//Transmit Packet
			IPEndPoint ^Remote = gcnew IPEndPoint(address, REMOTE_UDP_SOCKET);
			serverSocket->SendTo(sendBytes, byteId, System::Net::Sockets::SocketFlags::None, Remote);
		}
		catch (Exception ^)
		{
		}

Transmit Packet From Server Socket With Packet Sent Callback



	IPAddress ^address;
	int byteId;
	array<Byte>^sendBytes = gcnew array<Byte>(1500);

	try
	{
		if (!IPAddress::TryParse(DestIpAddressString, address))
		{
			//Invalid IP Address
			return;
		}
		byteId = 0;

		sendBytes[byteId++] = ;
		...
		sendBytes[byteId++] = ;

		//Transmit Packet
		IPEndPoint ^Remote = gcnew IPEndPoint(address, REMOTE_UDP_SOCKET);
		serverSocket->BeginSendTo(sendBytes, 0, byteId, System::Net::Sockets::SocketFlags::None, Remote, gcnew AsyncCallback(this, &myClassName::OurSendCallback), serverSocket);
		while (WaitingTxToComplete)
			Threading::Thread::Sleep(20);	//(Needed or deployment release version running from .exe will crash)

	}
	catch (Exception ^)
	{
	}

	//*************************************
	//*************************************
	//********** UDP TX CALLBACK **********
	//*************************************
	//*************************************
	void myClassName::OurSendCallback(IAsyncResult^ asyncResult)
    {
		serverSocket->EndSend(asyncResult);
		WaitingTxToComplete = false;
    }
Feel free to comment if you can add help to this page or point out issues and solutions you have found. I do not provide support on this site, if you need help with a problem head over to stack overflow.

Comments

Your email address will not be published. Required fields are marked *