C TCP Server in Windows – Thread per connection2 min read

A simple TCP server in C (windows). It works in a “thread per connection” way.

Note- I don’t know what I am doing.

#include <winsock.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/types.h>

#define PORT 50001

//Function that threads run
static DWORD __stdcall func(int s);

int main() {
  //Dont ask just put it in there
  WSADATA wsaData;
  if (WSAStartup(MAKEWORD(2, 0), & wsaData) != 0) {
    fprintf(stderr, "WSAStartup failed.\n");
    exit(1);
  }

  //Socket initiation
  int sock;
  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
    printf("Socket initiation failed!");
    return 0;
  }

  //Socket settings
  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(PORT);
  addr.sin_addr.s_addr = inet_addr("127.0.0.1");
  memset(addr.sin_zero, '\0', sizeof addr.sin_zero);

  //Bind the socket
  int b;
  if ((b = bind(sock, & addr, sizeof(addr))) == SOCKET_ERROR) {
    printf("Socket initiation failed!");
    return 0;
  }

  //Listen on socket
  int l = listen(sock, 25);

  printf("TCP server listening on port %d\n", PORT);

  //If (con) pass it to a new thread 
  while (1) {
    struct sockaddr_in client_addr;
    unsigned int c_len = sizeof client_addr;
    int s1 = accept(sock, & client_addr, & c_len);
    unsigned int cur_tid;

    _beginthreadex(NULL, 0, func, s1, 0, & cur_tid);
  }

  //Cleanup
  closesocket(sock);
  WSACleanup();
  return 0;
}

static DWORD __stdcall func(int s) {
  puts("Connection accepted");

  //Read data from client
  char buff[1024];
  unsigned int tot_bytes = recv(s, buff, sizeof(buff), MSG_PEEK);
  char * client_data = (char * ) malloc(tot_bytes + 1);
  for (int i = 0; i < (tot_bytes); i++) {
    client_data[i] = buff[i];
  }
  client_data[tot_bytes] = '\0';

  printf("Msg from client: %s\n", client_data);

  //Pretend you are processing info
  puts("Processing req");
  Sleep(5000);
  puts("Processing complete");

  //Prepare message for the client
  char * message;
  if (strcmp(client_data, "COMMAND1") == 0) {
    char lmsg[] = "COMMAND1 recieved";
    message = (char * ) malloc(strlen(lmsg));
    message = lmsg;
  } else if (strcmp(client_data, "COMMAND2") == 0) {
    char lmsg[] = "COMMAND2 recieved";
    message = (char * ) malloc(strlen(lmsg));
    message = lmsg;
  } else {
    char lmsg[] = "NO COMMAND recieved";
    message = (char * ) malloc(strlen(lmsg));
    message = lmsg;
  }

  free(client_data);

  //Send data to client
  send(s, message, strlen(message), 0);

  return 0;
}

TCP client in Node.js

var net = require('net');

var client1 = new net.Socket();
client1.connect(50001, '127.0.0.1', function() {
  console.log('Connected');
  client1.write('COMMAND1');
});

client1.on('data', function(data) {
  console.log('Received on 1: ' + data);
  client1.destroy();
});

client1.on('close', function() {
  console.log('Connection closed on 1');
});

var client2 = new net.Socket();
client2.connect(50001, '127.0.0.1', function() {
  console.log('Connected on 2');
  client2.write('COMMAND2');
});

client2.on('data', function(data) {
  console.log('Received on 2: ' + data);
  client2.destroy();
});

client2.on('close', function() {
  console.log('Connection closed on 2');
});

See single threaded windows TCP server using IO Completion Ports – https://github.com/hrishimk/iocp_tcp_server

Learning something new : RUST lang PART 32 min read

Error Handling

In the previous one where we built a guess the number game in rust, we did not handle any errors. The obvious error was that if something other than a number was inputted the program would crash.

Now that I have learnt how to correct this, lets change the code a little bit.

This was the code without error handling.

use std::io;

fn main() {

    println!("Guess a number");

    let stdin = io::stdin();
    let mut guess: i32;
    let mut line = String::new();

    //get user input
    stdin.read_line(&mut line).unwrap();

    //Parse input string to integer
    //Not error handled
    guess = line.trim().parse().unwrap();

}

The parse() method returns a result object. The result object would have Ok() and Err() values. So if it is OK we can run a function with the parsed value passed to it. If it is an error we can handle it gracefully and say “Listen idiot, you have to enter a number. A NUMBAAA”.

For this we use the match function or statement or whatever it is called. It seem to act like the switch statement.

So here is the update code for the number guessing game.

use std::io;

fn main() {

    println!("Guess a number");

    let stdin = io::stdin();
    let mut guess: i32;
    let mut line = String::new();

    //get user input
    stdin.read_line(&mut line).unwrap();

    //Parse input string to integer
    //Error handled 
    guess = match line.trim().parse() {
        Ok(num) => num,
        Err(_) =>{
            println!("Please enter a number");
            return;
        }
    };
}

With the loop and game –

use std::io;
extern crate rand;
use rand::Rng;

fn main() {
    //Generate a random number
    let num = rand::thread_rng().gen_range(0, 10);

    println!("Guess a number");

    let stdin = io::stdin();
    let mut guess: i32;

    while ( true ){
        let mut line = String::new();

        //get user input
        stdin.read_line(&mut line).unwrap();

        //Parse input string to integer
        //Error is handled
        guess = match line.trim().parse() {
            Ok(num) => num,
            Err(_) =>{
                println!("Please enter a number");
                continue;
            }
        };

        //If the guess is correct exit the loop
        if( guess == num ){
            println!("Correct the number was {}", guess);
            break;
        }
        else{
            println!("Wrong. Not {}", guess);
        }
    }
}

There you go rust book, I beat you at your own game.

//Also instead of using

while( true ){
    //code
}

//You could just do this

loop{
    //code
}

 

Learning something new : RUST lang PART 23 min read

The second part is creating a guessing game in rust.

From the book this is what is going to happen.

We’ll implement a classic beginner programming problem: a guessing game. Here’s how it works: the program will generate a random integer between 1 and 100. It will then prompt the player to enter a guess. After entering a guess, it will indicate whether the guess is too low or too high. If the guess is correct, the game will print congratulations and exit.

I tried to create a simple guessing game myself before looking at this. The program would ask the user for a number between 0 and 10.  If the input is equal to a random number generated by the program, the user wins.

But I needed to know

  • How to create a random number in rust within a given range/
  • How to get input from user.
  • How to convert the input string to an integer.

After a lot of google search and trial and error, I finally succeeded.

Random number generation

Using this package or what is known as crate in rust.

https://doc.rust-lang.org/rand/rand/index.html

Added this to the Cargo.toml file.

[dependencies]
rand = "0.3"

And the code –

extern crate rand;
use rand::Rng;

fn main() {
    let num = rand::thread_rng().gen_range(0, 10);
}

Getting input from user

use std::io;

fn main() {
    let stdin = io::stdin();
    let mut line = String::new();
    stdin.read_line(&mut line).unwrap();
}

Its done through the standard io (std::io) library.

Now what is that after the let keyword?

From what I understand, if you do not add mut after the let keyword, you are declaring a constant, but if you add mut its a variable.

If you are passing something by reference  like in

stdin.read_line(&mut line).unwrap();

If the function changes the value of the passed paramenter you should add &mut.

Examples –

fn main() {
    let a = 1;
    a = 5; //(Error: re-assignment of immutable variable)
}
fn main() {
    let mut a = 1;
    a = 5; //(No error)
}

More – https://doc.rust-lang.org/book/first-edition/mutability.html

.unwrap()

If there is and error, it would throw the error and exit the program.

Converting a string to an integer

use std::io;

fn main() {
    let stdin = io::stdin();
    let mut line = String::new();
    let mut num: i32;
    stdin.read_line(&mut line).unwrap();
    num = line.trim().parse().unwrap();
    println!("The number is {}", num);
}

Note – Not error handled, because I have no idea how to do it yet.

So, from what I found

  • you can declare and integer variable at top and set it value to string.parse() or
  • Use
    let num  = line.trim().parse::<i32>();

    and check for errors.

At last it is done

use std::io;
extern crate rand;
use rand::Rng;

fn main() {
    //Generate a random number
    let num = rand::thread_rng().gen_range(0, 10);
    
    println!("Guess a number");
    
    let stdin = io::stdin();
    let mut guess: i32;
    
    while ( true ){
        let mut line = String::new();
        
        //get user input
        stdin.read_line(&mut line).unwrap();
        
        //Parse input string to integer
        //Not error handled
        guess = line.trim().parse().unwrap();
        
        //If the guess is correct exit the loop
        if( guess == num ){
            println!("Correct the number was {}", guess);
            break;
        }
        else{
            println!("Wrong. Not {}", guess);
        }
    }

}

The guessing game – https://doc.rust-lang.org/book/second-edition/ch02-00-guessing-game-tutorial.html