Blog Image

guivi

About the blog

In this blog I will keep track of projects I develop though out this year and may be in the future. For now it is juts a testing ground for developing the blog itself but I hope as I put more material it will become a good place for me to hold information.

TCP Server in C++ for Linux and Windows

Uncategorised Posted on 14 Dec, 2020 08:54:26
#if defined(__WIN32)
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif
#include <winsock2,h>
#include <ws2tcpip.h>
#pragma comment (lib, "ws2_32.lib")

#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>

#endif

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#if defined(_WIN32)
#define ISVALIDSOCKET(s) ((s) != INVALIV_SOCKET)
#define CLOSESOCKET(s) closesocket(s)
#define GETSOCKETERRNO()(WSAGetLastError())

#else
#define ISVALIDSOCKET(s) ((s) >= 0)
#define CLOSESOCKET(s) close(s)
#define GETSOCKETERRNO()(errno)
#define SOCKET int
#endif

#if defined(_WIN32)
#include <conio.h>
#endif


int main(int argc, char* argv[])
{
#if defined(_WIN32)
    WSADATA d;
    if (WSAStartup(MAKEWORD( 2, 2), &d)){
        fprintf(stderr, "Failed to initialize.\n");
        return 1;
    }
#endif

    /// Configure ocal address for server.
    printf("Configuring local address...\n");
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    struct addrinfo *bind_address;
    getaddrinfo(0, "8080", &hints, &bind_address);

    /// Create scket.
    printf("Creting socket...\n");
    SOCKET socket_listner;
    socket_listner = socket(bind_address->ai_family, bind_address->ai_socktype, bind_address->ai_protocol);
    if (!ISVALIDSOCKET(socket_listner)){
        fprintf(stderr, "Coud not create socket (%d).\n", GETSOCKETERRNO());
        return 1;
    }

    /// Bind socket
    printf("Binding socket\n");
    if (bind(socket_listner, bind_address->ai_addr, bind_address->ai_addrlen)){
        fprintf(stderr, "Could not bind address (%d).\n", GETSOCKETERRNO());
        return 1;
    }
    freeaddrinfo(bind_address);

    /// Listen on the socket for connections
    printf("Listening...\n");
    if (listen(socket_listner, 10) < 0){
        fprintf(stderr, "Listening failed: (%d).\n", GETSOCKETERRNO());
        return 1;
    }

    fd_set master;
    FD_ZERO(&master);
    FD_SET(socket_listner, &master);
    SOCKET max_socket = socket_listner;

    printf("Waiting for connections...\n");
    while(1){
        fd_set reads;
        reads = master;
        if (select(max_socket, &reads, 0, 0, 0)){
            fprintf( stderr, "Select() failed. (%d).\n", GETSOCKETERRNO());
            return 1;
        }
        SOCKET i;
        for(i = 1; i <= max_socket; ++i){
            if (FD_ISSET(i, &reads)){
                if (i == socket_listner){   /// Is it a new client?
                    struct sockaddr_storage client_address;
                    socklen_t client_len = sizeof(client_address);
                    SOCKET socket_client = accept( socket_listner, (struct sockaddr*) &client_address, &client_len);
                    if (!ISVALIDSOCKET(socket_client)){
                        fprintf(stderr, "Accept() failed with error: (%d).\n", GETSOCKETERRNO());
                        return 1;
                    }

                    FD_SET(socket_client, &master);
                    if (socket_client > max_socket)
                        max_socket = socket_client;

                    char address_buffer[100];
                    getnameinfo((struct sockaddr*)&client_address, client_len, 
                        address_buffer, sizeof(address_buffer), 0, 0, NI_NUMERICHOST);
                    
                    printf("New connection from %s \n", address_buffer);
                }      
                else    /// Is not e listener. 
                {
                    char read[1024];
                    int bytes_received = recv(i, read, 1024, 0);
                    if (bytes_received < 1){
                        FD_CLR( i, &master);
                        CLOSESOCKET(i);
                        continue;
                    }
                    /*** DO SOMETHING WITH THE BUFFER DATA ***/
                }          
            }   /// if FD_ISSET.
        }   /// for i to max socket.
    }/// END while.

    printf("Closing listening....\n");
    CLOSESOCKET(socket_listner);

#if defined(_WIN32)
    WSACleanup();
#endif

    printf("Finished!");

    return 0;    
}


TCP Client in C++ for Linux and Windows.

Uncategorised Posted on 14 Dec, 2020 08:52:58
#if defined(__WIN32)
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif
#include <winsock2,h>
#include <ws2tcpip.h>
#pragma comment (lib, "ws2_32.lib")

#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>

#endif

#include <stdio.h>
#include <string.h>

#if defined(_WIN32)
#define ISVALIDSOCKET(s) ((s) != INVALIV_SOCKET)
#define CLOSESOCKET(s) closesocket(s)
#define GETSOCKETERRNO()(WSAGetLastError())

#else
#define ISVALIDSOCKET(s) ((s) >= 0)
#define CLOSESOCKET(s) close(s)
#define GETSOCKETERRNO()(errno)
#define SOCKET int
#endif

#if defined(_WIN32)
#include <conio.h>
#endif

int main(int argc, char* argv[])
{   
    /// Initialize Windows socket
#if defined(_WIN32)
    WSADATA d;
    if (WSASartup(MAKEWORD(2, 2), &d)){
        fprintf(stderr, "Failed to initialize.\n");
        return 1;
    }
#endif
    /// Checn numberof arguments is corect or print the help string
    if (argc != 3){
        fprintf(stderr, "usage: tcp_client hostname port.\n");
    }
    /// Get socket information for houst address.
    printf("Configure remote adress...\n");
    struct addrinfo hints;
    memset(&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_STREAM;
    struct addrinfo *peer_address;
    if (getaddrinfo(argv[1], argv[2], &hints, &peer_address)){
        fprintf(stderr, "getaddrinfo() failed. (%d)\n", GETSOCKETERRNO());
        return 1;
    }
    /// Print Socket information t screen
    printf("Remote address is: ");
    char address_buffer[100];
    char service_buffer[100];
    getnameinfo(peer_address->ai_addr, peer_address->ai_addrlen, 
        address_buffer, sizeof(address_buffer), 
        service_buffer, sizeof(service_buffer), NI_NUMERICHOST);
    printf("%s %s\n", address_buffer, service_buffer);

    /// Create socket.
    printf("Creating socket...\n");
    SOCKET socket_peer;
    socket_peer =socket(peer_address->ai_family, peer_address->ai_socktype, peer_address->ai_protocol);
    if (!ISVALIDSOCKET(socket_peer)){
        fprintf(stderr, "socket() failed (%d).\n", GETSOCKETERRNO());
        return 1;
    }

    /// Connect to peer.
    printf("Connecting...\n");
    if (connect(socket_peer, peer_address->ai_addr, peer_address->ai_addrlen)){
        fprintf(stderr, "connect() failed (%d).\n", GETSOCKETERRNO());
        return 1;
    }

    freeaddrinfo(peer_address); /// free the peer_address as we do not need any longer.

    printf("Connected.\n");
    printf("To send data enter text follow by enter.\n");

    /// The for ever client loop
    while(1){
        fd_set reads;
        FD_ZERO(&reads);
        FD_SET( socket_peer, &reads);
#if !defined(_WIN32)
        FD_SET(0, &reads);
#endif
        struct timeval timeout;
        timeout.tv_sec = 0;
        timeout.tv_usec = 100000;

        if (select(socket_peer+1, &reads, 0, 0, &timeout) < 0){
            fprintf(stderr, "select() failed. (%d)\n", GETSOCKETERRNO());
            return 1;
        } 

        if (FD_ISSET(socket_peer, &reads)){
            char read[4096];
            int bytes_received = recv(socket_peer, read, 4096, 0);
            if (bytes_received < 1){
                printf("Connection closed by peer.\n");
                break;
            }
            printf("Received (%d bytes): %s", bytes_received, read);
        }
#if defined(_WIN32)
        if (_kbhit()){
#else
        if (FD_ISSET(0, &reads)){
#endif
            char read[4096];
            if (!fgets(read, 4096, stdin))break;
            printf("Sending: %s", read);
            int bytes_send = send(socket_peer, read, strlen(read), 0);
            printf("Sent %d bytes.\n", bytes_send);
        }
    }/// while ends.

    printf("Close socket.\n");
    CLOSESOCKET(socket_peer);

#if defined(_WIN32)
    WSACleanup();
#endif

    printf("Finished.\n");
    return 0;
}