Tenouk C & C++ |< Winsock Prog. Example 3 | Main | Winsock Prog. Example 5 >| Site Index | Download | Linux Socket | Winsock in .NET


 

 

 

 

 

 

 

WINSOCK 2

WINDOWS SOCKET: PROGRAM EXAMPLES PART 4

 

 

 

 

 

 

 

What do we have in this chapter?

  1. Sending and Receiving (writing and reading) Data

  2. send() and recv() Server Program Example

  3. send() and recv() Client Program Example

  4. Notes for ATM

  5. connect()

  6. Return Values

  7. Remarks

  8. connect() Sever Program Example

  9. connect() Client Program Example

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Winsock Tutorial

 

Winsock: Story 1

Winsock: Story 2

Winsock: Story 3

Winsock: Example 1

Winsock: Example 2

Winsock: Example 3

Winsock: Example 4

Winsock: Example 5

Winsock: Example 6

Winsock: Example 7

Winsock: Example 8

Winsock: Example 9

Winsock: Example 10

Winsock: Example 11

Winsock: Example 12

Winsock: Reference 1

Winsock: Reference 2

Winsock: Reference 3

Winsock: Reference 4

Another Complete and Advanced C & Winsock2 Programming Tutorial

My Training Period:  xy hours

 

 

Machine’s OS is standalone Windows Xp Pro with SP2 except whenever mentioned.  Compiler used was Visual C++ 2003 .Net 1.1. Beware the codes that span more than one line.  Program examples have been tested for Non Destructive Test.  All information compiled for Windows 2000 (NT5.0) above and...

 

  1. The story was discussed at Winsock introduction story.

  2. Related functions, structures and macros used in the program examples have been dumped at Winsock structure & function 1 and Winsock structure & function 2.

  3. Other related and required information (if any) not available in no. 2 can be found at MSDN & Visual C++ online reference.

 

Skills to be acquired:

  • Able to understand the basic of networking such as TCP/IP.

  • Able to understand Winsock implementation and operations through the APIs and program examples.

  • Able to gather, understand and use the Winsock functions, structures and macros in your programs.

  • Able to build programs that use Microsoft C/Standard C programming language and Winsock APIs.

Sending and Receiving (writing and reading) Data

 

The following code demonstrates the send() and recv() functions (TCP packet).

For server program:

int bytesSent;

int bytesRecv = SOCKET_ERROR;

char sendbuf[200] = "Hello! I’m server, sending some test data.";

char recvbuf[200] = "";

 

bytesRecv = recv(m_socket, recvbuf, 32, 0);

printf("Bytes Recv: %ld\n", bytesRecv);

 

bytesSent = send(m_socket, sendbuf, strlen(sendbuf), 0);

printf("Bytes Sent: %ld\n", bytesSent);

 

For client program:

 

int bytesSent;

int bytesRecv = SOCKET_ERROR;

char sendbuf[200] = "Hello! I’m client, sending some test data.";

char recvbuf[200] = "";

 

bytesSent = send(m_socket, sendbuf, strlen(sendbuf), 0);

printf("Bytes Sent: %ld\n", bytesSent);

 

while(bytesRecv == SOCKET_ERROR)

{

    bytesRecv = recv(m_socket, recvbuf, 32, 0);

    if (bytesRecv == 0 || bytesRecv == WSAECONNRESET)

   {

        printf("Connection Closed.\n");

        break;

    }

    if (bytesRecv < 0)

        return;

    printf("Bytes Recv: %ld\n", bytesRecv);

}

 

 

In this code, two integers are used to keep track of the number of bytes that are sent and received. The send() and recv() functions both return an integer value of the number of bytes sent or received, respectively, or an error. Each function also takes the same parameters: the active socket, a char buffer, and the number of bytes to send or receive, and any flags to use. Use recvfrom() and sendto() functions for the connectionless socket such as for the User Datagram Protocol (UDP). The following is our complete send, receive and read data for the client and server program examples. Firstly we run the server program to listen for connection.

 

send() and recv() Server Program Example

// Microsoft Development Environment 2003 - Version 7.1.3088

// Copyright (r) 1987-2002 Microsoft Corporation. All Right Reserved

// Microsoft .NET Framework 1.1 - Version 1.1.4322

// Copyright (r) 1998-2002 Microsoft Corporation. All Right Reserved

//

// Run on Windows XP Pro machine, version 2002, SP 2

//

// <windows.h> already included

// WINVER = 0x0501 for Xp already defined in windows.h

// Server program, using TCP

 

#include <stdio.h>

#include <winsock2.h>

 

int main()

{

WORD wVersionRequested;

WSADATA wsaData;

int wsaerr;

 

// Using MAKEWORD macro, Winsock version request 2.2

wVersionRequested = MAKEWORD(2, 2);

 

wsaerr = WSAStartup(wVersionRequested, &wsaData);

if (wsaerr != 0)

{

    /* Tell the user that we could not find a usable WinSock DLL.*/

    printf("Server: The Winsock dll not found!\n");

    return 0;

}

else

{

       printf("Server: The Winsock dll found!\n");

       printf("Server: The status: %s.\n", wsaData.szSystemStatus);

}

 

/* Confirm that the WinSock DLL supports 2.2.*/

/* Note that if the DLL supports versions greater    */

/* than 2.2 in addition to 2.2, it will still return */

/* 2.2 in wVersion since that is the version we      */

/* requested.                                        */

if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 )

{

    /* Tell the user that we could not find a usable WinSock DLL.*/

    printf("Server: The dll do not support the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));

    WSACleanup();

    return 0;

}

else

{

       printf("Server: The dll supports the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));

       printf("Server: The highest version this dll can support: %u.%u\n", LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));

}

 

//////////Create a socket////////////////////////

//Create a SOCKET object called m_socket.

SOCKET m_socket;

 

// Call the socket function and return its value to the m_socket variable.

// For this application, use the Internet address family, streaming sockets, and

// the TCP/IP protocol.

// using AF_INET family, TCP socket type and protocol of the AF_INET - IPv4

m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

 

// Check for errors to ensure that the socket is a valid socket.

if (m_socket == INVALID_SOCKET)

{

    printf("Server: Error at socket(): %ld\n", WSAGetLastError());

    WSACleanup();

    return 0;

}

else

{ printf("Server: socket() is OK!\n"); }

 

////////////////bind//////////////////////////////

// Create a sockaddr_in object and set its values.

sockaddr_in service;

 

// AF_INET is the Internet address family.

service.sin_family = AF_INET;

// "127.0.0.1" is the local IP address to which the socket will be bound.

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

// 55555 is the port number to which the socket will be bound.

service.sin_port = htons(55555);

 

// Call the bind function, passing the created socket and the sockaddr_in structure as parameters.

// Check for general errors.

if (bind(m_socket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR)

{

    printf("Server: bind() failed: %ld.\n", WSAGetLastError());

    closesocket(m_socket);

    return 0;

}

else

{

    printf("Server: bind() is OK!\n");

}

 

// Call the listen function, passing the created socket and the maximum number of allowed

// connections to accept as parameters. Check for general errors.

if (listen(m_socket, 10) == SOCKET_ERROR)

    printf("Server: listen(): Error listening on socket %ld.\n", WSAGetLastError());

else

{

   printf("Server: listen() is OK, I'm waiting for connections...\n");

}

 

// Create a temporary SOCKET object called AcceptSocket for accepting connections.

SOCKET AcceptSocket;

 

// Create a continuous loop that checks for connections requests. If a connection

// request occurs, call the accept function to handle the request.

printf("Server: Waiting for a client to connect...\n" );

printf("***Hint: Server is ready...run your client program...***\n");

// Do some verification...

while (1)

{

    AcceptSocket = SOCKET_ERROR;

    while (AcceptSocket == SOCKET_ERROR)

    {

        AcceptSocket = accept(m_socket, NULL, NULL);

    }

 

// else, accept the connection...

// When the client connection has been accepted, transfer control from the

// temporary socket to the original socket and stop checking for new connections.

printf("Server: Client Connected!\n");

m_socket = AcceptSocket; 

break;

}

 

int bytesSent;

int bytesRecv = SOCKET_ERROR;

char sendbuf[200] = "This string is a test data from server";

// initialize to empty data...

char recvbuf[200] = "";

 

// Send some test string to client...

printf("Server: Sending some test data to client...\n");

bytesSent = send(m_socket, sendbuf, strlen(sendbuf), 0);

 

if (bytesSent == SOCKET_ERROR)

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

else

{

       printf("Server: send() is OK.\n");

       printf("Server: Bytes Sent: %ld.\n", bytesSent);

}

 

// Receives some test string from client...and client

// must send something lol...

bytesRecv = recv(m_socket, recvbuf, 200, 0);

 

if (bytesRecv == SOCKET_ERROR)

       printf("Server: recv() error %ld.\n", WSAGetLastError());

else

{

       printf("Server: recv() is OK.\n");

       printf("Server: Received data is: \"%s\"\n", recvbuf);

       printf("Server: Bytes received: %ld.\n", bytesRecv);

}

 

WSACleanup();

return 0;

}

 

Sample output:

Windows socket program example output screen: more using send() and recv()

 

Figure 1

 

The server program is listening to and waiting for connection. While this program is running, run the following client program.

 

send() and recv() Client Program Example

// Microsoft Development Environment 2003 - Version 7.1.3088

// Copyright (r) 1987-2002 Microsoft Corporation. All Right Reserved

// Microsoft .NET Framework 1.1 - Version 1.1.4322

// Copyright (r) 1998-2002 Microsoft Corporation. All Right Reserved

//

// Run on Windows XP Pro machine, version 2002, SP 2

//

// <windows.h> already included

// WINVER = 0x0501 for Xp already defined in windows.h

// A sample of client program using TCP

 

#include <stdio.h>

#include <winsock2.h>

 

int main()

{

    // Initialize Winsock.

    WSADATA wsaData;

    int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);

    if (iResult != NO_ERROR)

              printf("Client: Error at WSAStartup().\n");

    else

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

 

    // Create a socket.

    SOCKET m_socket;

    m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

 

    if (m_socket == INVALID_SOCKET)

    {

        printf("Client: socket() - Error at socket(): %ld\n", WSAGetLastError());

        WSACleanup();

        return 0;

    }

   else

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

 

    // Connect to a server.

    sockaddr_in clientService;

 

    clientService.sin_family = AF_INET;

    // Just test using the localhost, you can try other IP address

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

    clientService.sin_port = htons(55555);

 

    if (connect(m_socket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)

    {

        printf("Client: connect() - Failed to connect.\n");

        WSACleanup();

        return 0;

    }

    else

    {

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

       printf("Client: Can start sending and receiving data...\n");

    }

 

    // Send and receive data.

    int bytesSent;

    int bytesRecv = SOCKET_ERROR;

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

    char sendbuf[200] = "This is a test string from client";

    char recvbuf[200] = "";

 

       // Receives some test string to server...

       while(bytesRecv == SOCKET_ERROR)

       {

           bytesRecv = recv(m_socket, recvbuf, 200, 0);

        if (bytesRecv == 0 || bytesRecv == WSAECONNRESET)

        {

             printf("Client: Connection Closed.\n");

            break;

        }

 

        if (bytesRecv < 0)

            return 0;

       else

       {

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

              printf("Client: Received data is: \"%s\"\n", recvbuf);

              printf("Client: Bytes received is: %ld.\n", bytesRecv);

       }

    }

 

       // Sends some test data to server...

       bytesSent = send(m_socket, 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);

              printf("Client: The test string sent: \"%s\"\n", sendbuf);

       }

 

    WSACleanup();

    return 0;

}

 

Sample output:

Windows socket program example output screen: using send(), recv() for client

 

Figure 2

 

And the previous server console output is shown below that complete the server-client communication.

 

Windows socket program example output screen: using send(), recv() for server

 

Figure 3

 

Try running the client program from different machines and change the server IP address accordingly. Another more flexible client-server program example is given at the end of this note.

 

Notes for ATM

 

The following are important issues associated with connection setup, and must be considered when using Asynchronous Transfer Mode (ATM) with Windows Sockets 2:

  1. The accept() and WSAAccept() functions do not necessarily set the remote address and address length parameters. Therefore, when using ATM, the caller should use the WSAAccept() function and place ATM_CALLING_PARTY_NUMBER_IE in the ProviderSpecific member of the QOS structure, which itself is included in the lpSQOS parameter of the callback function used in accordance with WSAAccept().

  2. When using the accept() function, realize that the function may return before connection establishment has traversed the entire distance between sender and receiver. This is because the accept() function returns as soon as it receives a CONNECT ACK message; in ATM, a CONNECT ACK message is returned by the next switch in the path as soon as a CONNECT message is processed (rather than the CONNECT ACK being sent by the end node to which the connection is ultimately established). As such, applications should realize that if data is sent immediately following receipt of a CONNECT ACK message, data loss is possible, since the connection may not have been established all the way between sender and receiver.

 

connect()

 

Item

Description

Function

connect().

Use

Establishes a connection to a specified socket.

Prototype

int connect(SOCKET s, const struct sockaddr* name, int namelen);

Parameters

s - [in] Descriptor identifying an unconnected socket.

name - [in] Name of the socket in the sockaddr structure to which the connection should be established.

namelen - [in] Length of name, in bytes.

Return value

See below.

Include file

<winsock2.h>

Library

ws2_32.lib

Remark

See below.

 

Table 1

 

Return Values

 

If no error occurs, connect() returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError(). On a blocking socket, the return value indicates success or failure of the connection attempt. With a non-blocking socket, the connection attempt cannot be completed immediately. In this case, connect() will return SOCKET_ERROR, and WSAGetLastError() will return WSAEWOULDBLOCK. In this case, there are three possible scenarios:

  1. Use the select() function to determine the completion of the connection request by checking to see if the socket is writeable.

  2. If the application is using WSAAsyncSelect() to indicate interest in connection events, then the application will receive an FD_CONNECT notification indicating that the connect operation is complete (successfully or not).

  3. If the application is using WSAEventSelect() to indicate interest in connection events, then the associated event object will be signaled indicating that the connect operation is complete (successfully or not).

 

Until the connection attempt completes on a non-blocking socket, all subsequent calls to connect() on the same socket will fail with the error code WSAEALREADY, and WSAEISCONN when the connection completes successfully. Due to ambiguities in version 1.1 of the Windows Sockets specification, error codes returned from connect() while a connection is already pending may vary among implementations. As a result, it is not recommended that applications use multiple calls to connect() to detect connection completion. If they do, they must be prepared to handle WSAEINVAL and WSAEWOULDBLOCK error values the same way that they handle WSAEALREADY, to assure robust execution. If the error code returned indicates the connection attempt failed (that is, WSAECONNREFUSED, WSAENETUNREACH, WSAETIMEDOUT) the application can call connect() again for the same socket.

 

Error code

Meaning

WSANOTINITIALISED

A successful WSAStartup() call must occur before using this function.

WSAENETDOWN

The network subsystem has failed.

WSAEADDRINUSE

The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error usually occurs when executing bind(), but could be delayed until this function if the bind was to a partially wildcard address (involving ADDR_ANY) and if a specific address needs to be committed at the time of this function.

WSAEINTR

The blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall().

WSAEINPROGRESS

A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.

WSAEALREADY

A non-blocking connect call is in progress on the specified socket.

In order to preserve backward compatibility, this error is reported as WSAEINVAL to Windows Sockets 1.1 applications that link to either Winsock.dll or Wsock32.dll.

WSAEADDRNOTAVAIL

The remote address is not a valid address (such as ADDR_ANY).

WSAEAFNOSUPPORT

Addresses in the specified family cannot be used with this socket.

WSAECONNREFUSED

The attempt to connect was forcefully rejected.

WSAEFAULT

The name or the namelen parameter is not a valid part of the user address space, the namelen parameter is too small, or the name parameter contains incorrect address format for the associated address family.

WSAEINVAL

The parameter s is a listening socket.

WSAEISCONN

The socket is already connected (connection-oriented sockets only).

WSAENETUNREACH

The network cannot be reached from this host at this time.

WSAENOBUFS

No buffer space is available. The socket cannot be connected.

WSAENOTSOCK

The descriptor is not a socket.

WSAETIMEDOUT

Attempt to connect timed out without establishing a connection.

WSAEWOULDBLOCK

The socket is marked as non-blocking and the connection cannot be completed immediately.

WSAEACCES

Attempt to connect datagram socket to broadcast address failed because setsockopt() option SO_BROADCAST is not enabled.

 

Table 2

 

Remarks

 

The connect() function is used to create a connection to the specified destination. If socket s, is unbound, unique values are assigned to the local association by the system, and the socket is marked as bound.

For connection-oriented sockets (for example, type SOCK_STREAM), an active connection is initiated to the foreign host using name (an address in the namespace of the socket). If a socket is opened, a setsockopt() call is made, and then a sendto() call is made, Windows Sockets performs an implicit bind() function call. When the socket call completes successfully, the socket is ready to send and receive data. If the address member of the structure specified by the name parameter is all zeroes, connect will return the error WSAEADDRNOTAVAIL. Any attempt to reconnect an active connection will fail with the error code WSAEISCONN.

For connection-oriented, non-blocking sockets, it is often not possible to complete the connection immediately. In such a case, this function returns the error WSAEWOULDBLOCK. However, the operation proceeds.

When the success or failure outcome becomes known, it may be reported in one of two ways, depending on how the client registers for notification.

 

For a connectionless socket (for example, type SOCK_DGRAM), the operation performed by connect() is merely to establish a default destination address that can be used on subsequent send()/ WSASend() and recv()/ WSARecv() calls. Any datagrams received from an address other than the destination address specified will be discarded. If the address member of the structure specified by name is all zeroes, the socket will be disconnected. Then, the default remote address will be indeterminate, so send()/ WSASend() and recv()/ WSARecv() calls will return the error code WSAENOTCONN. However, sendto()/ WSASendTo() and recvfrom()/ WSARecvFrom() can still be used. The default destination can be changed by simply calling connect again, even if the socket is already connected. Any datagrams queued for receipt are discarded if name is different from the previous connect.

For connectionless sockets, name can indicate any valid address, including a broadcast address. However, to connect to a broadcast address, a socket must use setsockopt() to enable the SO_BROADCAST option. Otherwise, connect will fail with the error code WSAEACCES. When a connection between sockets is broken, the sockets should be discarded and recreated. When a problem develops on a connected socket, the application must discard and recreate the needed sockets in order to return to a stable point.

 

connect() Sever Program Example

 

The following example demonstrates the use of the connect() function for client and server. Firstly run the server program and then the client.

// Microsoft Development Environment 2003 - Version 7.1.3088

// Copyright (r) 1987-2002 Microsoft Corporation. All Right Reserved

// Microsoft .NET Framework 1.1 - Version 1.1.4322

// Copyright (r) 1998-2002 Microsoft Corporation. All Right Reserved

//

// Run on Windows XP Pro machine, version 2002, SP 2

//

// <windows.h> already included

// WINVER = 0x0501 for Xp already defined in windows.h

// Server program, using TCP

 

#include <stdio.h>

#include <winsock2.h>

 

int main()

{

WORD wVersionRequested;

WSADATA wsaData;

int wsaerr;

// Using MAKEWORD macro, Winsock version request 2.2

wVersionRequested = MAKEWORD(2, 2);

 

wsaerr = WSAStartup(wVersionRequested, &wsaData);

if (wsaerr != 0)

{

    /* Tell the user that we could not find a usable WinSock DLL.*/

    printf("Server: The Winsock dll not found!\n");

    return 0;

}

else

{

       printf("Server: The Winsock dll found!\n");

       printf("Server: The status: %s.\n", wsaData.szSystemStatus);

}

 

/* Confirm that the WinSock DLL supports 2.2.*/

/* Note that if the DLL supports versions greater    */

/* than 2.2 in addition to 2.2, it will still return */

/* 2.2 in wVersion since that is the version we      */

/* requested.                                        */

if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 )

{

    /* Tell the user that we could not find a usable WinSock DLL.*/

    printf("Server: The dll do not support the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));

    WSACleanup();

    return 0;

}

else

{

       printf("Server: The dll supports the Winsock version %u.%u!\n", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion));

       printf("Server: The highest version this dll can support: %u.%u\n", LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion));

}

 

//////////Create a socket////////////////////////

//Create a SOCKET object called m_socket.

SOCKET m_socket;

 

// Call the socket function and return its value to the m_socket variable.

// For this application, use the Internet address family, streaming sockets, and the TCP/IP protocol.

// using AF_INET family, TCP socket type and protocol of the AF_INET - IPv4

m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

 

// Check for errors to ensure that the socket is a valid socket.

if (m_socket == INVALID_SOCKET)

{

    printf("Server: Error at socket(): %ld\n", WSAGetLastError());

    WSACleanup();

    return 0;

}

else

{

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

}

 

////////////////bind//////////////////////////////

// Create a sockaddr_in object and set its values.

sockaddr_in service;

 

// AF_INET is the Internet address family.

service.sin_family = AF_INET;

// "127.0.0.1" is the local IP address to which the socket will be bound.

// Try your machine IP address...

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

// 55555 is the port number to which the socket will be bound…

// Try other non-standard ports ( > 1024). Max = 2 power to 16 = 65536

service.sin_port = htons(55555);

 

// Call the bind function, passing the created socket and the sockaddr_in structure as parameters.

// Check for general errors.

if (bind(m_socket, (SOCKADDR*)&service, sizeof(service)) == SOCKET_ERROR)

{

    printf("Server: bind() failed: %ld.\n", WSAGetLastError());

    closesocket(m_socket);

    return 0;

}

else

{

    printf("Server: bind() is OK!\n");

}

 

// Call the listen function, passing the created socket and the maximum number of allowed

// connections to accept as parameters. Check for general errors.

if (listen(m_socket, 10) == SOCKET_ERROR)

     printf("Server: listen(): Error listening on socket %ld.\n", WSAGetLastError());

else

{

     printf("Server: listen() is OK, I'm waiting for connections...\n");

}

 

// Create a temporary SOCKET object called AcceptSocket for accepting connections.

SOCKET AcceptSocket;

 

// Create a continuous loop that checks for connections requests. If a connection

// request occurs, call the accept function to handle the request.

printf("Server: Waiting for a client to connect...\n" );

printf("***Hint: Server is ready...run your client program...***\n");

// Do some verification...

while (1)

{

    AcceptSocket = SOCKET_ERROR;

    while (AcceptSocket == SOCKET_ERROR)

    {

        AcceptSocket = accept(m_socket, NULL, NULL);

    }

 

    // else, accept the connection...

    // When the client connection has been accepted, transfer control from the

    // temporary socket to the original socket and stop checking for new connections.

    printf("Server: Client Connected!\n");

    m_socket = AcceptSocket; 

    break;

}

 

WSACleanup();

return 0;

}

 

Sample output:

Windows socket program example output screen: using connect()

 

Figure 4

 

While the server program is in listening mode, run the following client program.

 

connect() Client Program Example

 

The following is the client program to test the previous connect() function.

#include <stdio.h>

#include <winsock2.h>

 

int main()

{

  // Initialize Winsock

  WSADATA wsaData;

  int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);

  if (iResult != NO_ERROR)

    printf("Client: Error at WSAStartup().\n");

  else

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

 

  // Create a SOCKET for connecting to server

  SOCKET ConnectSocket;

  ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

  if (ConnectSocket == INVALID_SOCKET)

  {

    printf("Client: Error at socket(): %ld\n", WSAGetLastError());

    WSACleanup();

    return 0;

  }

  else

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

 

  // The sockaddr_in structure specifies the address family,

  // IP address, and port of the server to be connected to.

  sockaddr_in clientService;

  clientService.sin_family = AF_INET;

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

  clientService.sin_port = htons(55555);

 

  // Connect to server...

  if (connect(ConnectSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)

  {

    printf("Client: Failed to connect.\n");

    WSACleanup();

    return 0;

  }

  else

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

 

  printf("Client: Connected to server...\n");

  WSACleanup();

  return 0;

}

 

Sample output:

Windows socket program example output screen: using connect() for client

 

Figure 5

 

And the previous server program’s console output is shown below.

 

Windows socket program example output screen: using connect() for server

 

Figure 6

 

Notes for IrDA Sockets:

  1. The af_irda.h header file must be explicitly included.

  2. If an existing IrDA connection is detected at the media-access level, WSAENETDOWN is returned.

  3. If active connections to a device with a different address exist, WSAEADDRINUSE is returned.

  4. If the socket is already connected or an exclusive/multiplexed mode change failed, WSAEISCONN is returned.

  5. If the socket was previously bound to a local service name to accept incoming connections using bind(), WSAEINVAL is returned. Note that once a socket is bound, it cannot be used for establishing an outbound connection.

 

IrDA implements the connect function with addresses of the form sockaddr_irda. Typically, a client application will create a socket with the socket() function, scan the immediate vicinity for IrDA devices with the IRLMP_ENUMDEVICES socket option, and choose a device from the returned list, form an address and then call connect(). There is no difference between blocking and non-blocking semantics.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Further reading and digging:

 

  1. Linux Sockets: Story and program examples.

  2. Linux and TCP/IP.

  3. A complete info on Windows socket reference from MSDN which include managed and unmanaged API doc.

  4. Structure, enum, union and typedef story can be found struct, enum, union & typedef tutorial.

  5. For Multibytes, Unicode characters and Localization please refer to Multibyte, Unicode and wide characters (Story) and Win32 Windows & Users tutorial (Implementation).

  6. Windows data type information is Win32 - Windows data types.

  7. Check the best selling C / C++ and Windows books at Amazon.com.

 

 

 

 

 

 

 


 

Tenouk C & C++ |< Winsock Prog. Example 3 | Main | Winsock Prog. Example 5 >| Site Index | Download | Linux Socket | Winsock in .NET