article

Rudimentary UDP with Winsocks

Email
Submitted on: 1/5/2015 10:31:00 PM
By: Ixac (from psc cd)  
Level: Beginner
User Rating: By 2 Users
Compatibility: Microsoft Visual C++
Views: 2428
 
     The article demonstrates using Winsocks for rudimentary communication with UDP


 
				
Rudimentary UDP with Winsocks

Two simple console based programs demonstrate UDP with Winsocks. The client simply sends packets of data typed in by the user and the server displays it. The code is more of a reference for starting applications that require Winsocks.

Server Code
  • Create a new Win32 Console application in VC++ 6.0.
  • Add a new CPP file to this project.
  • Copy and paste the Server code in this new file and compile the project.
#include <iostream.h>
#include <Winsock2.h>

void ReportError (const char* const szErr)
{
  cout << szErr << endl;
}

int main (void)
{
  // Initialize Windows Sockets
  WORD wVersionRequired = MAKEWORD (2, 2);
  WSADATA wd;
  int iReturn = ::WSAStartup (wVersionRequired, &wd);
  if (iReturn != 0)
    return ReportError ("WSAStartup failed."), 0;

  // Create the socket
  SOCKET sock = ::WSASocket (AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
  if (sock == INVALID_SOCKET)
    return ReportError ("WSASocket failed."), ::WSACleanup (), 0;

  // Get the name of the local computer
  char szHostName [MAX_PATH];
  ::gethostname (szHostName, sizeof szHostName);

  // Fill in the sockaddr_in structure for binding
  sockaddr_in sa;
  sa.sin_family = AF_INET;
  ::WSAHtons (sock, 8080, &sa.sin_port);

  // Get the IP address of the local computer name
  HOSTENT* phe = ::gethostbyname (szHostName);
  memcpy (&sa.sin_addr, phe->h_addr_list [0], phe->h_length);

  // Pad with zeros
  ZeroMemory (sa.sin_zero, sizeof sa.sin_zero);

  // Bind to a port
  iReturn = ::bind (sock, reinterpret_cast <sockaddr*> (&sa),
    sizeof sockaddr_in);
  if (iReturn == SOCKET_ERROR)
    return ReportError ("bind failed."), ::closesocket (sock),
    ::WSACleanup (), 0;

  // Prepare receive buffer(s)
  WSABUF wbRecv [1];
  char szRecvBuf [1][256];
  wbRecv [0].len = 256;
  wbRecv [0].buf = szRecvBuf [0];
 
  // Receive the first line of data
  DWORD dwBytesReceived = 0, dwFlags = 0;
  INT nFromLen = sizeof sockaddr_in;
  if ((iReturn = ::WSARecvFrom (sock, wbRecv, 1,
    &dwBytesReceived, &dwFlags,
    reinterpret_cast <sockaddr*> (&sa), &nFromLen,
    NULL, NULL)) == 0)
  {
    // Output Received data till a 'Close' is received.
    do
    {
      cout << "Data: " << wbRecv [0].buf << ", Read: "
        << dwBytesReceived << " bytes" <<
        ", From IP: " << ::inet_ntoa (sa.sin_addr) << endl;

      // Reset in - out parameters
      nFromLen = sizeof sockaddr_in;
      dwFlags = 0;
    }
    while (lstrcmpi (wbRecv [0].buf, "Close") != 0
      && ::WSARecvFrom (sock, wbRecv, 1,
      &dwBytesReceived, &dwFlags,
      reinterpret_cast <sockaddr*> (&sa), &nFromLen,
      NULL, NULL) == 0);
  }
  else
  {
    // Report Recv errors
    char szError [256];
    wsprintf (szError,
      "WSARecvFrom failed and returned: %d. "
      "WSAGetLastError: %d", iReturn,
      WSAGetLastError ());
      ReportError (szError);
  }

  // Close the socket
  ::closesocket (sock);
 
  // Uninitialize Windows Sockets
  ::WSACleanup ();

  return 0;
}
 
Client Code
  • Create another new Win32 Console application in VC++ 6.0.
  • Add a new CPP file to this project.
  • Copy and paste the Client code in this new file and compile the project.
#include <iostream.h>
#include <Winsock2.h>
#include <stdio.h>

void ReportError (const char* const szErr)
{
  cout << szErr << endl;
}

int main (void)
{
  // Initialize Windows Sockets
  WORD wVersionRequired = MAKEWORD (2, 2);
  WSADATA wd;
  int iReturn = ::WSAStartup (wVersionRequired, &wd);
  if (iReturn != 0)
    return ReportError ("WSAStartup failed."), 0;

  // Create the socket
  SOCKET sock = ::WSASocket (AF_INET, SOCK_DGRAM, 0, 0, 0, 0);
  if (sock == INVALID_SOCKET)
    return ReportError ("WSASocket failed."), ::WSACleanup (), 0;

  // Fill in the sockaddr_in structure for sending
  sockaddr_in sa;
  sa.sin_family = AF_INET;
  ::WSAHtons (sock, 8080, &sa.sin_port);

  // Fill in the IP address of the machine where the
  // server resides

  sa.sin_addr.S_un.S_addr = ::inet_addr ("xxx.xxx.xxx.xxx");
  // Substitute "xxx.xxx.xxx.xxx" with a valid IP

  // Pad with zeros
  ZeroMemory (sa.sin_zero, sizeof sa.sin_zero);

  // Prepare receive buffer(s)
  WSABUF wbSend [1];
  char szSendBuf [1][512];
  wbSend [0].len = 512;
  wbSend [0].buf = szSendBuf [0];

  // Receive the first line of data
  DWORD dwBytesSent = 0;
  INT nToLen = sizeof sockaddr_in;

  cout << ">" << flush;
  char szGet [402];
  gets (szGet);

  DWORD dwTickCount = GetTickCount ();
  wsprintf (wbSend [0].buf, "%lu %s", dwTickCount, szGet);

  if ((iReturn = ::WSASendTo (sock, wbSend, 1,
    &dwBytesSent, NULL,
    reinterpret_cast <sockaddr*> (&sa),
    nToLen, NULL, NULL)) == 0)
  {
    // Output Sent data till an 'Exit' is typed
    do
    {
      cout << "Data: " << wbSend [0].buf << ", Sent: "
        << dwBytesSent << endl;

      cout << ">" << flush;
      gets (szGet);

      dwTickCount = GetTickCount ();
      wsprintf (wbSend [0].buf, "%lu %s", dwTickCount, szGet);

      // Reset in - out parameters
      nToLen = sizeof sockaddr_in;
      dwBytesSent = 0;
    }
    while (lstrcmpi (szGet, "Exit") != 0
      && ::WSASendTo (sock, wbSend, 1,
      &dwBytesSent, NULL,
      reinterpret_cast <sockaddr*> (&sa),
      nToLen, NULL, NULL) == 0);
  }
  else
  {
    // Report Recv errors
    char szError [256];
    wsprintf (szError,
      "WSASendTo failed and returned: %d. "
      "WSAGetLastError: %d", iReturn,
    WSAGetLastError ());
    ReportError (szError);
  }

  // Close the socket
  ::closesocket (sock);

  // Uninitialize Windows Sockets
  ::WSACleanup ();

  return 0;
}

Once the client and the server program is compiled then run both at the same time. Make sure that the IP used in the client is correct. Also make sure that the port number used in the server as well as the client is the same.


Other 1 submission(s) by this author

 


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this article (in the Beginner category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments


 There are no comments on this submission.
 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular article, please click here instead.)
 

To post feedback, first please login.