Python vs C – How simple is it to write a pair of communicating sockets?

Lately I have been reading a lot of articles online written to compare Python to other languages. It is not a secret to anyone that the Python community is growing, and along with it, is the number of people who promote/recommend this language, of course.

Let me not add up to the already large mass of those articles by boasting about Python’s usability, speed and practicality, but rather, I will compare the two languages by writing a small socket client/server pair in each of those languages.

But first, let me give you some of my personal opinions about both the languages since I know them well enough. C is very dear to me, not only because it was the first language I had ever learnt, but also because it runs most of the GNU, and GNU is well, very dear to me! C also happens to be my only second language of choice, after Python (although I know bits of Java, I prefer not to use it, not sure why, but I hate it). I have been programming in Python only from the last couple of months and I was really impressed. I solve HackerEarth and CodeChef problems as a pass time. Although I could do all of the problems I have done in C, doing them in Python took like 1/10th of the time (literally!) and 1/10th the typing effort. I would admit, C is much more fun to write than Python, simply because you ‘feel’ the code is yours, and I love to code C whenever I am free, will I use it in an environment where time is the priority? Probably not. Maybe when C is the only way out, but most of the time, I am better off writing it in Python.

That being said, the popularity of C doesn’t get any less, and it is going to stay that way as long as, maybe the Internet. Here’s something I found.

https://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
You see the thing on top there? Yes, it is there for a reason. To make it short, C is powerful, very powerful. C gives you access to things you can not really imagine in other languages. On the other hand, Python is practical, flexible, and easy to learn. Web apps, sockets, Raspberry Pi, Arduino, Android or anything else you can imagine, there has to be a library made for it by someone, somewhere.

The code part.

I am giving the client and server code in both the languages here as is. No explanation and stuff, because that’s not the topic here. Note that all the source codes are tested running OK on Kali 1.0.6, gcc and all stock stuff, so it should be not much trouble to get it running. Windows guy, search for gcc directory and run it over the command prompt. It won’t run from any IDE.

Python

Writing a pair of communicating TCP sockets require around 30 minutes along with the understanding part, if you have got some background in networking. Python does most of the stuff for you, and you just create a socket variable, supply host and port and that’s it. Rest is left to your imagination (or not, I got too carried away!). Here comes the code:
client.py

import socket
s = socket.socket()
host = socket.gethostname()
port = 1356 
s.connect((host, port))
shit = s.recv(1024)
print shit
s.close()
server.py

s = socket.socket()
host = socket.gethostname()
s.bind((host, 1356))
s.listen(5)
while True:
    c, addr = s.accept()
    c.send("Message from server")
    c.close()

And that is it. Even if it looks lame (which it is), it is the maybe the simplest thing that qualifies to be called a server/client.

C

Now lets write the same in C. This is around 4 times the size of Python code, and much of the stuff are done by hand (nothing new for C, I suppose). This code is the shortest I could cut it to, and just does one simple task. Sends the “Client talking loud!\n” message to server over port 1356 on localhost. The parameters can be edited as per convenience to suit any inter network testing, but that’s the most this code will do. Nevertheless, this is a TCP client/server model.
client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>

int main(int argc, char **argv) {
int sock, port, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
port = atoi("1356");
sock = socket(AF_INET, SOCK_STREAM, 0);
server = gethostbyname("127.0.0.1");
bzero((char *)&serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(port);
connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
bzero(buffer, 256);
strcpy(buffer, "Client talking loud!\n");
write(sock, buffer, strlen(buffer));
close(sock);
}

server.c

#include <stdio.h> 
#include <strings.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>


int main(int argc, char **argv) {
int sock, nsock, port;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
sock = socket(AF_INET, SOCK_STREAM, 0);
bzero((char*)&serv_addr, sizeof(serv_addr));
port = atoi("1356");
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(port);
bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
listen(sock, 2);
clilen = sizeof(cli_addr);
nsock = accept(sock, (struct sockaddr *)&cli_addr, &clilen);
bzero(buffer, 256);
read(nsock, buffer, 255);
printf("%s\n", buffer);
close(sock);
close(nsock);
}

Here is the expected output:

Sorry, there is no commenting in the above code, and it really needs some explanation. I would’ve written them, but then, the code would have grown three folds (LOL)! It will need another nice article to explain all the stuff from that client.c and server.c code. I will conclude here. Thank you for reading 🙂

Update: If you happen to run any of the above code, make sure you run server first!