a Medically trained Computer Scientist

Refactor

You have seen how easy it is too make a server-client program in go that communicates within the same computer. Next, let us make the code more readable and streamlined. Sending back data from server to client isn’t really useful when we are building a program to locate a ‘missing’ laptop. Remove func reader(r io.Reader) function and go reader(c).

Also, variable incoming is more descriptive than just fd in server.go. We also rename echoServer to what_is_the_ip instead.

Next, we want to factor out magic strings in our code. We focus on net.Listen("unix", "/tmp/echo.sock"). Put these two parameters into constants.

Flags

It is possible to combine the server.go and client.go into a single file. We can take command line arguments passed into our compiled program. Within the main() function, we run off correspond function based to the argument being passed on.

Notice that I put the code inside init() function. This is a special go way that will run before main(). It is sorts of initialization part of the program.
- StringVar tells go that it expects a string.
- &mode is the address of the variable that will store user’s input.
- "m" is the name of the flag for mode of operation.
- "server" is the default parameter is the user do not pass in any.
- Lastly, "Mode: -m server|client" shows the help usage when user runs ./main --help in the terminal.

All of these are generated by go itself which is very convenient.

I also define our global variables. While global variable is bad in general, it is okay to use it here for commonly used variables.

Timestamp

While it is nice to see external IP being sent to the server, it would be nicer if we have a timestamp printed on the console as well. Let’s modify the code:

We use a built in library, time to get current time in RFC850 format. A number of other formats are available from https://golang.org/pkg/time/. We store the current time inside time variable and append ip address received from client. We also need to import the time library.

import("log""net""time")

Ten seconds is too often. Let’s change it to every ten minutes instead.

time.Sleep(time.Duration(pollMinutes)*time.Minute)

IP Lookup

So far, we have been only sending local ip address. This isn’t half useful if we want to find our missing laptop across the world. We need to be able to send client’s external IP address to the client. One easy way is to use a publicly available api.

[]whatismyipaddress.com](whatismyipaddress.com) provides an api to retrieve external IP address. Using http.Get, we use a normal http GET request to the api and store its result into response variable. We read the whole thing with ReadAll and put it into a string as src.

File Log

We want to have a log file that records all incoming data from client. There are many ways of data persistence. Simplest is just store them in a text file.

First, we create a text file in the current directory with createFile(fileName string) function. Since we want to be as restrictive as possible, we create the text file with 0600 octal permission. Wel also make sure to append, not to overwrite the file to preserve all existing data.

Run them

Build the file (this time it is just single file!) go build main.go.

To run as a server, just type ./main. For a client, type ./main -m client. The program will use port 8088 by default if no port is specified.