< More Winsock2 APIs | Winsock2 Main | Connectionless-UDP, Client & Server >


 

 

An Intro to Windows Socket Programming with C

Part 5

 

 

What do we have in this chapter 1 part 5?

  1. TCP Sender/client Program Example

  2. Testing the TCP Client and Server Programs

  3. Testing the TCP Client and Server Programs in Private Network

 

TCP Sender/client Program Example

 

1.      While in the Visual C++ IDE, click File menu > Project sub menu to create a new project.

2.      Select Win32 for the Project types: and Win32 Console Application for the Templates:. Put the project and solution name. Adjust the project location if needed and click OK.

3.      Click Next for the Win32 Application Wizard Overview page. We will remove all the unnecessary project items.

4.      In the Application page, select Empty project for the Additional options:. Leave others as given and click Finish.

 

Windows socket and C programming: creating new TCP client/sender program

 

5.      Next, we need to add new source file. Click Project menu > Add New Item sub menu or select the project folder in the Solution Explorer > Select Add menu > Select New Item sub menu.

6.      Select C++ File (.cpp) for the Templates:. Put the source file name and click Add. Although the extension is .cpp, Visual C++ IDE will recognize that the source code used is C based on the Compile as C Code (/TC) option which will be set in the project property page later.

 

Windows socket and C programming: addin new C++ source file for the existing TCP Winsock program

 

7.      Now, add the source code as given below.

 

#include <winsock2.h>

#include <stdio.h>

 

int main(int argc, char **argv)

{

     WSADATA              wsaData;

     SOCKET               SendingSocket;

     // Server/receiver address

     SOCKADDR_IN          ServerAddr, ThisSenderInfo;

     // Server/receiver port to connect to

     unsigned int         Port = 7171;

     int  RetCode;

     // Be careful with the array bound, provide some checking mechanism...

     char sendbuf[1024] = "This is a test string from sender";

     int BytesSent, nlen;

 

     // Initialize Winsock version 2.2

     WSAStartup(MAKEWORD(2,2), &wsaData);

     printf("Client: Winsock DLL status is %s.\n", wsaData.szSystemStatus);

 

     // Create a new socket to make a client connection.

     // AF_INET = 2, The Internet Protocol version 4 (IPv4) address family, TCP protocol

     SendingSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

     if(SendingSocket == INVALID_SOCKET)

     {

          printf("Client: socket() failed! Error code: %ld\n", WSAGetLastError());

          // Do the clean up

          WSACleanup();

          // Exit with error

          return -1;

     }

     else

          printf("Client: socket() is OK!\n"); 

 

     // Set up a SOCKADDR_IN structure that will be used to connect

     // to a listening server on port 5150. For demonstration

     // purposes, let's assume our server's IP address is 127.0.0.1 or localhost

 

     // IPv4

     ServerAddr.sin_family = AF_INET;

     // Port no.

     ServerAddr.sin_port = htons(Port);

     // The IP address

     ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1");

 

     // Make a connection to the server with socket SendingSocket.

     RetCode = connect(SendingSocket, (SOCKADDR *) &ServerAddr, sizeof(ServerAddr));

     if(RetCode != 0)

     {

          printf("Client: connect() failed! Error code: %ld\n", WSAGetLastError());

          // Close the socket

          closesocket(SendingSocket);

          // Do the clean up

          WSACleanup();

          // Exit with error

          return -1;

     }

     else

     {

          printf("Client: connect() is OK, got connected...\n");

          printf("Client: Ready for sending and/or receiving data...\n");

     }

 

     // At this point you can start sending or receiving data on

     // the socket SendingSocket.

 

     // Some info on the receiver side...

     getsockname(SendingSocket, (SOCKADDR *)&ServerAddr, (int *)sizeof(ServerAddr));

     printf("Client: Receiver IP(s) used: %s\n", inet_ntoa(ServerAddr.sin_addr));

     printf("Client: Receiver port used: %d\n", htons(ServerAddr.sin_port));

 

     // Sends some data to server/receiver...

     BytesSent = send(SendingSocket, sendbuf, strlen(sendbuf), 0);

 

     if(BytesSent == SOCKET_ERROR)

          printf("Client: send() error %ld.\n", WSAGetLastError());

     else

     {

          printf("Client: send() is OK - bytes sent: %ld\n", BytesSent);

          // Some info on this sender side...

          // Allocate the required resources

          memset(&ThisSenderInfo, 0, sizeof(ThisSenderInfo));

          nlen = sizeof(ThisSenderInfo);

 

          getsockname(SendingSocket, (SOCKADDR *)&ThisSenderInfo, &nlen);

          printf("Client: Sender IP(s) used: %s\n", inet_ntoa(ThisSenderInfo.sin_addr));

          printf("Client: Sender port used: %d\n", htons(ThisSenderInfo.sin_port));

          printf("Client: Those bytes represent: \"%s\"\n", sendbuf);

     }

 

     if( shutdown(SendingSocket, SD_SEND) != 0)

          printf("Client: Well, there is something wrong with the shutdown().

                    The error code: %ld\n", WSAGetLastError());

     else

          printf("Client: shutdown() looks OK...\n");

     // When you are finished sending and receiving data on socket SendingSocket,

     // you should close the socket using the closesocket API. We will

     // describe socket closure later in the chapter.

     if(closesocket(SendingSocket) != 0)

          printf("Client: Cannot close \"SendingSocket\" socket. Error code: %ld\n", WSAGetLastError());

     else

          printf("Client: Closing \"SendingSocket\" socket...\n");

 

     // When your application is finished handling the connection, call WSACleanup.

     if(WSACleanup() != 0)

          printf("Client: WSACleanup() failed!...\n");

     else

          printf("Client: WSACleanup() is OK...\n");

     return 0;

}

 

8.      Build and run the program. The following screenshot shows a sample expected output if there is no error during the build and run stages. The 10061 error code indicates that there is no listening socket for the given IP address and port number. We need to run the server/receiver first.

 

---------------------------------------------------------------

Windows socket and C programming: The TCp client in action with connection refused error code

 

Testing the TCP Client and Server Programs

 

1.      In this test, firstly run the server program and you may also want to run the netstat program.

 

Windows socket and C programming: running the select TCP server program

 

2.      Then, run the client program several times (make sure before the timeout occur. However you can increase the timeout values in the program if needed).

 

Windows socket and C programming: the TCP client program run smoothly

 

3.      The previous server sample output is shown below with the client was run two times.

 

Windows socket and C programming: the TCP select server output console sample with three client connections

 

Testing the TCP Client and Server Programs in Private Network

 

In this test we are using different hosts in a private network. The receiver IP address is 192.168.1.1 and the sender is 192.168.1.1. We change those address in the sender program and then rebuild it. The receiver is listening on all interfaces.

 

1.      Firstly, we run the server program.

2.      Then, we run the sender program two times.

3.      The following first screenshot show the receiver sample output and the second is the sender.

 

Windows socket and C programming: the TCP select server in action in the private network

 

Windows socket and C programming: the TCP sender console output sample

 

 

 


< More Winsock2 APIs | Winsock2 Main | Connectionless-UDP, Client & Server >