Cross Codes Blog

Blog home

Introduction to Socket programming in C (part 3)

30 August 2018 | Engineering

Here is the code for Linux and Windows for this tutorial. Assuming you are using Linux, extract the compressed file with the command tar -xzvf socket.tar.gz. In the resulting socket directory, you will find source code for the server and client as well as a makefile to compile them. From the makefile, you have the option of the following commands:

make # standard compile
make debug # compile with debugging symbols
make clean # remove binary files

After compiling the code, run the server using the command ./server&. The '&' makes this run in the background. You can now run the client using the command ./client insert message here. If done correctly, the server should print the message you specified via command line argument when running the client. The output should look like the following:

Watch out for the following errors
1. If there is a bind failure, that means a server might still be running on the specified port and IP address. To verify this, use the ps command to show the currently running processes. To kill the server, use either kill [pid#] or pkill server. Notice in the code you can also change the port. Both the client and the server will need the same port number to connect to each other.
2. If there is a connect failure, the client failed to reach the server due to attempting to connect to the wrong address or the server either terminated unexpected (possibly due to the first error) or it isn't running at all. In the code provided, the IP addresses and port numbers of the server and client are the same so it is unlikely that this error will be caused by the former.

Introduction to Socket programming in C (part 2)

30 August 2018 | Engineering

Here are the steps to utilize Socket programming. The example code shown are snippets of a program where the server listens for a client that contains a message to be printed to stdout. The code will be provided in part 3 of this blog post.

1. You need descriptors for the server socket to listen and the client socket to receive from. In order to bind them, you will need to create a struct sockaddr that will contain the IP address and port number. The length of this struct will also be needed as an argument for some Socket functions. Lastly, you need a buffer to store message contents to be sent or received.

2. Simply create the socket.

3. In order to bind the socket, you need to initialize the sockaddr struct to contain the protocol, IP address, and port number. Bind the socket and be sure to use the sizeof operator for the length of the struct.

4. Now that the socket is binded, you can have it listen for incoming sockets.

5. In order to achieve a connection between the server and the client, assign the client socket to accept given the server socket.

6. It is now possible to send or receive messages. For sending messages, use the message string length and for receiving, use the buffer size.

7. DO NOT forget to close your sockets when they are no longer in use. This will allow the used ports and IP addresses to be available for new sockets.

1. You will need a descriptor for the client socket to connect to the server. Using a struct sockaddr will store the needed IP address and port number needed to achieve the connection. Lastly, you will need a buffer to store message contents to be sent or received.

2. Simply create the socket.

3. Similarly to bind, the sockaddr struct will need to be initialized in order for the client to connect to the server.

4. At this point, you can send or receive messages.

5. Once again, close the socket when finished.

Read part 3

Introduction to Socket programming in C (part 1)

30 August 2018 | Engineering

What are Sockets?
Sockets are abstractions that contain the necessary implementation to connect clients and servers over a networked connection in order to provide communication between systems. In a Socket implemented application, a server contains the socket to listen for client bound sockets reaching out on a specified IP address and port in order to form a connection. Sockets are very widely used in networked systems and applications. Examples of programs that utilize sockets are instant messaging apps and cloud storage. In this blog post, I will be discussing the basic universal semantics in C to form a Socket based communication. Familiarize yourself with the Socket state diagram below that shows the basic control flow:

For this tutorial, we will be using the following methods from the Socket API:
int socket(int domain, int type, int protocol)
An unsigned int value is returned based on the numerical quantity of the socket created. Any socket returning a negative value determines a failed attempt in creating the socket.
domain: protocol to use determined by Socket constant
type: how to communicate with protocol determined by Socket constant
protocol: protocol value (0 for IP)

int bind(int socket, const struct sockaddr * address, socklen_t address_length)
An unsigned int value is returned upon successful attachment of the socket to the given address and port. A negative value determines a failure to connect to the given address and port.
socket: integer value corresponding to a given socket to bind
address: struct containing network routing information including IP address and port number
address_length: length of the struct in bytes

int listen(int socket, int back_log)
The server waits to receive a connection from a client. If this value is negative, the server cannot receive any communication.
socket: integer value corresponding to given socket to receive inbound communication
back_log: maximum length in bytes for queue of pending communication

int accept(int socket, struct sockaddr * address, socklen_t address_length)
A positive integer determines that an inbound socket has been detected and accepted. A negative integer determines a failure to accept the inbound socket.
socket: integer value corresponding to given socket to accept inbound communication
address: struct containing network routing information including IP address and port number
address_length: length of the struct in bytes

int connect(int socket, const struct sockaddr * address, socklen_t address_length)
Connects the client socket to the server socket. A negative value determines a connection failure.
socket: integer value corresponding to given socket to connect to the server
address: struct containing network routing information including IP address and port number
address_length: length of the struct in bytes

ssize_t send(int socket, const void * buffer, size_t buffer_length, int flags)
Returns the size in bytes of an outbound message. A negative value determines a failure to send the message.
socket: integer value corresponding to given socket with message to send
buffer: message contents being sent
buffer_length: size of message
flags: send flag determined by Socket constant or 0

int recv(int socket, void * buffer, size_t buffer_length, int flags)
Returns the size in bytes of an inbound message. A negative value determines a failure to receive the message.
socket: integer value corresponding to given socket with message to receive
buffer: message contents being received
buffer_length: size of message
flags: receive flag determined by Socket constant or 0

int close(int socket)
Remove the socket from memory in order to make the IP address and port available for another socket. This returns a negative value if the given socket doesn't exist.
socket: integer value corresponding to given socket to remove from memory

Quick note: Because Socket functions can fail, it is good practice to return with an error code if their return values determine failure. Also, you will typically need a buffer to make use of sockets. This is the container that gets sent through the socket that enables communication.

Read part 2

Networking culture in software engineering

28 August 2018 | Experience

I have noticed a a subculture among software engineers that presents a fondness for professional networking. This is what inspired the creation of Crosscodes in my case; to showcase my professional work and experience while job hunting, and to document what I have learned in my career on this blog. This experience typically begins in university where students are adamant in obtaining a quantity of technical skills from their classes whilst performing at the highest caliber possible. A software engineer with an ideal attitude is described as "one who is always hungry to learn". The goal is to be professionally competitive in terms of experience in order to gain access to higher standing careers. Through academics, this can be achieved through GPA, awards, recognition, projects, letters of recommendation, degrees, and technical knowledge. Outside of academics, one can also seek more experience through engineering organizations, outside projects, hackathons, internships, and relevant employment. The presence of this experience follows with the steps to land an engineering title under a respectable company and acquire even more technical skills. A good place to start in one's job hunting journey are career fairs where multiple companies are arranged in panels where participants can showcase their resumes and electronic portfolios or relevant work. Hackathons also typically have company panels where showcasing one's resume is also appropriate in addition to submitting a winning hack. Companies present at hackathons typically assess participants' performance based on their hack. This makes hackathons a perfect place to showcase one's technical ability since companies use these events to look for potential candidates. While software engineers taking part in this networking culture are selling their competencies, companies are looking for engineers to invest in since they can provide valuable assets. Thus, companies are also competing to hire and compensate engineers to the best of their ability. I have also seen job fairs and professional networking events happening within engineering organizations. One's resume is their best friend when marketing their skills. It is also appropriate in casual settings to showcase one's resume therefore, always having one at hand is good practice. There have been multiple times where I have been asked for my resume in casual settings when I gave off hints of being a software engineer in search of a job; to where I reply by presenting the link to this website. These casual settings can happen anywhere including company social gatherings where the purpose is for engineers to get to know each other in terms of who posses what skill set, and bond to form a team. One looking to move up the ranks within their company can take advantage of this setting by chatting with higher experienced individuals. Individuals who have taken an extra step in this networking culture have created websites to not only showcase their experience, but present it in a personal way thereby proving technical competencies in web development in particular but more importantly, validating presentation skills and showing a uniqueness in personality. Having a LinkedIn and/ or GitHub account are also great ways for one to present their experience and have an online persona. This contributes to a world wide web of software engineers available to connect and compete for networking power in order to gain the upper advantage. I have also noticed individuals blogging or publishing specific work or articles while connecting with other software engineers either for mentoring, or to expand their networking power. Keep in mind that soft skills should not be ignored. In fact, a common mistake for some individuals is spending too much time harnasing their technical skills while neglecting their soft skills. To stand out even further, one will want to have good communication skills and be presentable. This involves but is not limited to being able to communicate effectively in a panel, showcasing slide shows, being organized, punctual, and being a leader and a team player. Although this blog post was focused on the technical aspect of the networking culture, that is only one out of many aspects to consider when being professionally competitive.

Answering the salary question

24 August 2018 | Industry

Whether it's a job application, phone screen, or interview, chances are you will be asked to put a quantitative mark on your salary expectations. When searching for a job, this can feel uneasy for an applicant because they would not want to over estimate and appear too expensive or arrogant to be given a job offer. The same applies on the opposite side of the spectrum where no one would want to low-ball themselves and be stuck with limited job offers. From research, experience, and mentoring from individuals who have experience in the industry, I present some tips on how to address the salary question given certain scenarios.

Do your research
First of all, it is important to understand that salary is only one out of multiple compensations that a company has to offer. One mustn't forget about health benefits, 401k, paid vacation, personal time, work hour options, ability to work remotely, company culture, location, etc. All of these factors should be weighted in when deciding to apply for a company based on its perks. There is no utopian company so compensate accordingly. Some good links to start research on company perks are:

If you are going to negotiate your salary, have an idea of what you are worth based on the skill set you have to offer. As of writing this blog post, the average starting salary for software engineers in San Diego is $78,501 according to Google. Location is also a determining factor of salary. If you must provide a specific answer for your salary expectations, use a range based on substantial research. Also be sure you are comfortable with the lower end of the range of what you ask for. Of course, it is preferable to defer an answer for your salary which I will explain below.

Job Application
Usually, job applications that ask for your expected salary provide a list of salary ranges. Once again, do your research and be sure you are okay with being paid in the low end of that range. If it's an open-ended input, then you can defer your answer by tying "negotiable", "applicable", "open", etc. I normally put "up for in-person discussion". This prevents you from being eliminated for being too expensive or from limiting yourself to accepting a lower pay just to be hired.

Phone screening
You may be asked about your salary expectations during a phone screen. Be careful as going too high may eliminate you from being considered. Going too low is also not the ideal way to approach it. Depending on the employer, they may be checking to see whether you value your work. A good approach is to go on the offensive within reason. It is okay to reply; "On average, how much is offered for this position?" Telling the recruiter that you did research can be risky. Data you find may not be up-to-date or you might appear to be bargaining the company giving the impression that you might be difficult to work with. Also consider taking a more defensive approach. "I would like to discuss this later in the application process in the event that I am hired. I trust that what you have to offer your candidates are competitive based on the impression I have of this company." If all fails and a number must be given, refer to your research and more importantly, be humble but confident. In this case, it may be ideal to take the offensive approach.

Unless you have been given the offer up front, take the same approach I mentioned in the phone screening section of the application process. Once you do get the offer, this is the ideal time to actively negotiate your salary. Know your value and do your research to ensure that you and the company get the most out of the negotiation. Also, if you are this far in the application process, do not be afraid to go slightly above the market. At the very least, you might be paid above your baseline. This also lets the interviewer know that you value your work and are willing to do the job in a worthwhile manner for you are an investment to the company.

To conclude, it is important to be humble in the process of answering the salary question. Do your research on the company, job position, and location and base your answer from that. If possible, defer your answer until you are given the offer. Once you made it that far, it is then preferable to be confident in negotiating a specific mark. Also, never be timid about salary question. Part of it is an assessment of your confidence and self-worth.

Bad superblock remedy

21 August 2018 | Technical

There have been multiple times where I have experienced Linux booting into the temporary root file system "initramfs". After doing some research, this seems to happen due to a bad superblock typically resulting from an unexpected shutdown. This was very prominent in Linux Mint 18.3 Sylvia when my laptop battery would die. In this blog post, I present a remedy for bad superblocks that has consistently worked for me. If the following cannot be done through the terminal when you boot, you will need to make a bootable flash drive with Linux and do the following from there. To learn how to make a bootable flash drive, please see my blog post Dual booting a Windows machine.

Repairing the superblock:
#List all available partitions; '*' marks the partition of your Linux install
sudo fdisk -l|grep Linux|grep -Ev 'swap'
/dev/sda1 2048 204587007 204584960 97.6G 83 Linux
/dev/sda2 * 204587008 214351871 9764864 4.7G 83 Linux
/dev/sda4 224116736 419428351 195311616 93.1G 83 Linux

#List all superblocks; '/dev/sda2' is my partition, replace that with where YOUR partition is
sudo dumpe2fs /dev/sda2 | grep superblock
Primary superblock at 0, Group descriptors at 1-6
Backup superblock at 32768, Group descriptors at 32769-32774
Backup superblock at 98304, Group descriptors at 98305-98310
Backup superblock at 163840, Group descriptors at 163841-163846
Backup superblock at 229376, Group descriptors at 229377-229382
Backup superblock at 294912, Group descriptors at 294913-294918
Backup superblock at 819200, Group descriptors at 819201-819206
Backup superblock at 884736, Group descriptors at 884737-884742
Backup superblock at 1605632, Group descriptors at 1605633-1605638
Backup superblock at 2654208, Group descriptors at 2654209-2654214
Backup superblock at 4096000, Group descriptors at 4096001-4096006
Backup superblock at 7962624, Group descriptors at 7962625-7962630
Backup superblock at 11239424, Group descriptors at 11239425-11239430
Backup superblock at 20480000, Group descriptors at 20480001-20480006
Backup superblock at 23887872, Group descriptors at 23887873-23887878

#Choose alternate superblock and repair it; '-y' flag automatically answers 'yes' to all questions; I chose block 32768
sudo fsck -b 32768 /dev/sda2 -y
fsck 1.40.2 (12-Jul-2007)
e2fsck 1.40.2 (12-Jul-2007)
/dev/sda2 was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Free blocks count wrong for group #241 (32254, counted=32253).
Fix? yes
Free blocks count wrong for group #362 (32254, counted=32248).
Fix? yes
Free blocks count wrong for group #368 (32254, counted=27774).
Fix? yes
/dev/sda2: ***** FILE SYSTEM WAS MODIFIED *****
/dev/sda2: 59586/30539776 files (0.6% non-contiguous), 3604682/61059048 blocks

#Finally mount the partition; remember to use YOUR partition, mine is '/dev/sda2'
sudo mount /dev/sda2 /mnt

Hopefully this was helpful to anyone that has ever experienced this problem. Feel free to contact me for any concerns.

Partitioning hard drives in Windows

29 July 2018 | Technical

Before using your hard drive, you typically need to allocate space and assign each allocated space to a particular purpose in order for your OS to gain access to it. By default, there are usually partitions for recovery purposes or anything that has to do with system embedded software. If you are nit picky about organizing your hard drive like myself, it may be in your favor to partition your hard drive(s) in a way that you find organized by allocating specific areas for whatever general data you want that area for. Also, it is favorable to make sure you are actually using all the space you need that is installed in your system. If you want to make a multiboot system, partitioning will also need to be done to allocate space for specific operating systems. OS installers normally prompt users to a hard drive partitioning menu. In windows, you can use the "Computer Management" app or type in "diskmgmt.msc" in the DOS prompt to access the app. You might need to run it as administrator since you are modifying system hardware. The app looks like the following:

To partition, you simply right click on any unallocated area and allocate some if not all the space left. However, it is preferable to do this prior to installing an operating system in order to prevent space gaps once a system is already installed. Also, partitioning on already allocated areas WILL format that area in your hardrive so be careful and BACK UP all your data before attempting to do any repartitioning. Anything with unallocated space is however safe to touch.

Resume tips

14 July 2018 | Industry

We have all gone through the insatiably repetitive task of updating and proof reading our resumes in order to maximize the quality of how we sell ourselves to the industry. Before I go into the few tips I'd like to share about writing resumes, I would like to mention a few principles to consider regarding resumes. First off, your resume is your marketing tool therefore, it is vital that it goes through substantial edits and feedback from multiple eyes. Everyone has different ideas for what makes a resume good but the ideas that matter are those who have the recruiting power. Thus, the more people you can get to review your resume, the more information you have on marketing yourself optimally to the perspective of others. Another point to mention is that a recruiter will spend an average of 5-10 seconds looking at your resume so plan accordingly to best communicate your experience and format in a quick read friendly way. Now to discuss some tips on writing your resume:

- adopt a mindset that you can never write the perfect resume and be prepared to take constructive criticism; the more flexible you are, the better ability you have in writing a good resume
- NO MORE than one page; if it's over a page, it's a CV so make it work
- avoid having a high concentrated area of text in order to make your resume more desirable to read within a few seconds
- it helps to bold keywords
- numerical metrics look good (ie. "design saved 45 watts of power"; "cut costs by 14%"")
- conserve space; you only have a page (only put job relevant information that can actually help your chances of getting hired)
- objectives/ summaries are a waste of space; whatever job you apply for, the recruiter already knows your objective which is obviously to land that job so just get to the point with your skills and experience
- school projects are frowned upon but if you have no other experience, strive to explain your project in a way that APPLIES relevant skills (ie. "implemented autocomplete algorithm for user generated text" rather than "programmed multiway trie")
- go out of your way to do projects; there's plenty of tutorials online that can apply and sharpen your skills
- use "achiever" rather than "doer" statements for your descriptions (ie. "proposed agreement with payroll contractors slashing labor costs by 10%" rather than "negotiated with payroll contractors")
- send text versions of your resume; there's a good chance that the selection process is computerized and based on keyterms present in resumes; see how your resume looks using ATS (Applicant Tracking System)
- hyperlinks look good for showing proof of your projects but keep the format (don't use hyperlink default format)
- anything you write on your resume is fair game for interview questions so STUDY; the point of your resume is to land the interview, once that is accomplished, the next step is making sure you are prepared to talk about everything in your resume
- keep resume up-to-date; in the unfortunate event you are unemployed for an extended period, do projects and put them in your resume
- unless your relevant experience was temporary work, it's a rule of thumb to add relavant employment only if it lasted for at least a year
- use generic words when labeling sections to make it easy for ATS to read resume (you should have terms such as skills, experience, employment, certifications etc.)
- avoid naming your sections with obscure terms (ie. skills instead of competencies, work/ employment over professional)
Here's a link I stumbled into that gave me resume feedback and my current resume

2 Arduino projects

24 June 2018 | Engineering

While participating in ESW, I have gotten a handful of experience working outside the scope of software. The sustainability projects I helped develop utilized an electrical engineering aspect involving an Arduino microcontroller. From these projects, I learned how to wire an electrical component to an Arduino as well as coding in Arduino's embedded environment through its IDE; in addition to learning some basic analog circuitry required to power the circuit design. Below, I present two links to tutorials that helped me complete these projects:

Dot Matrix Scrolling Text
In my project for Solar Chill, I was tasked with building a circuit for a scrolling text that would display the carbon emissions saved over time. We used a dot matrix for the text interface and programmed each individual character to be properly displayed using corresponding dots. Programming text characters was done in C and the display in Arduino's embedded environment.

Android Bluetooth Communication
In my project for Solar Interact, my team of software engineers and my colleague's team of electrical engineers were to collaborate in implementing a communication network through Bluetooth. The electrical team soldered the circuit to send and receive information between Android and Arduino and came up with the embedded software that tells the Arduino the communication protocol. My team of programmers used the Android Bluetooth library in Android studio to communicate with the Arduino. We also implemented a UI that displays the information to the user in the form of a graph using Graphview which utilized the Bluetooth sockets for its information.

Including multiple Lua scripts

2 June 2018 | Engineering

I have recently posted about implementing Wireshark dissectors in Lua. You may have been wondering whether it is possible to include multiple Lua scripts in the main driver in order to keep your Lua code base more organized. This can be accomplished by storing variables and functions within a file to be treated as a class in a dictionary and returning that dictionary. Then from the driver, simply type the require statement and assign it to an alias that treats the calling file as an object and using the alias as an object reference, call the specific function or variable. The require function takes the directory of the file to include as parameter but with "." as a folder separator. DO NOT add ".lua" in the filename. See below for examples:

Calling file:
-- dictionary to store fields and functions
local dict = {}

-- values to store in dictionary
local variable = ""
local function method(--[[ parameters ]])
   -- function code

-- store values in dictionary
dict.v = variable
dict.m = method

-- return the dictionary
return dict

Driver file:
-- require statement
local callee = require("")

-- call fields using object reference

<< < 1 2 3 4 > >>

© Copyright 2018 Jeremy Cruz