# `sockchat`

Chat with unlimited number of peers through a variety of sockets.

`sockchat` is a simple [client-server][] [online chat][] application with a
[terminal user interface][]. Both the client and the server are bundled into
the same executable. One of the main goals is to support a broad variety of
communication protocols, see [usage](#usage).

`sockchat` was written for educational purposes under a fairly short time and
consists of less than 600 lines of portable [POSIX 2004][], [C99][] code. Some
of the things explored:

-   Standard C:
    -   [`errno.h`][], thorough error handling.
    -   [`stdarg.h`][], useful and convenient logging and error reporting.
-   POSIX:
    -   [`getopt`][], robust command line interface.
    -   [`sys/socket.h`][], Berkley sockets.
    -   [`sys/select.h`][], local and network I/O multiplexing.
    -   [`netdb.h`][], network protocols.
    -   [`search.h`][], data structures.
    -   [`termios.h`][], simple text-based user interface.
-   Software design:
    -   [Data-centered design][].
    -   Low [coupling][].
    -   Narrow variable [scope][]s.
    -   79 [characters per line][], consistent breaking strategies.
    -   Horrible, horrible [macros][].

[Client-server]: https://en.wikipedia.org/wiki/Client-server
[Online chat]: https://en.wikipedia.org/wiki/Online_chat
[Terminal user interface]: https://en.wikipedia.org/wiki/Terminal_user_interface
[POSIX 2004]: https://pubs.opengroup.org/onlinepubs/009695399/toc.htm
[C99]: https://en.wikipedia.org/wiki/C99
[`errno.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html
[`stdarg.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdarg.h.html
[`getopt`]: https://pubs.opengroup.org/onlinepubs/009695399/functions/getopt.html
[`sys/socket.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_socket.h.html
[`sys/select.h`]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_select.h.html
[`netdb.h`]: https://pubs.opengroup.org/onlinepubs/009695399/basedefs/netdb.h.html
[`search.h`]: https://pubs.opengroup.org/onlinepubs/009695399/basedefs/search.h.html
[`termios.h`]: https://pubs.opengroup.org/onlinepubs/007904975/basedefs/termios.h.html
[Data-centered design]: https://lwn.net/Articles/193245/
[Coupling]: https://en.wikipedia.org/wiki/Coupling_(computer_programming)
[Scope]: https://en.wikipedia.org/wiki/Scope_(computer_science)
[Characters per line]: https://en.wikipedia.org/wiki/Characters_per_line
[Macros]: https://en.wikipedia.org/wiki/C_preprocessor

## Usage

See also [examples](#examples).

`sockchat --help`:

```
sockchat 1.0 - Chat with unlimited number of peers through a variety of sockets

Usage:
  sockchat (server|client) [options]
  sockchat -h|--help
  sockchat --version

Options:
  -f <family>    [default: INET]
  -t <socktype>  [default: DGRAM]
  -p <protocol>  [default: 0]
  -n <node>      [default: ]
  -s <service>   [default: 3200]

Recognized values for <family>:
  UNSPEC
  UNIX
  LOCAL
  INET
  INET6
  PACKET

Recognized values for <socktype>:
  0
  STREAM
  DGRAM
  SEQPACKET
  RAW
  RDM
  PACKET

Recognized values for <protocol>:
  0
  IP
  TCP
  UDP
  UDPLITE
  SCTP
  ICMP
```

## Building

A simple [`Makefile`](Makefile) is provided, build with

```sh
make
```

## Installation

The produced executable can be run from anywhere. It can however be installed
with

```sh
make install
```

## Implementation notes

## Examples

<table>
<tr>
<th>Server</th>
<th>Client Alice</th>
<th>Client Bob</th>
</tr>
<tr>
<td style="vertical-align: top;">
<pre>
$ sockchat server
Info: Using buffer size 255
Info: Trying to bind...
Info: Succeeded to bind
Info: Client '[192.168.0.3:50453] Alice' joined
Info: Client '[192.168.0.4:48678] Bob' joined
Info: Client '[192.168.0.3:50453] Alice' sent 11 bytes
Info: Client '[192.168.0.4:48678] Bob' sent 13 bytes
Info: Client '[192.168.0.3:50453] Alice' left
Info: Client '[192.168.0.4:48678] Bob' left
</pre>
</td>
<td style="vertical-align: top;">
<pre>
$ sockchat client
Info: Using buffer size 255
Info: Trying to connect...
Info: Succeeded to connect
User name: Alice
[192.168.0.3:50453] Alice: Hello Bob!
[192.168.0.4:48678] Bob: Hello Alice!
</pre>
</td>
<td style="vertical-align: top;">
<pre>
$ sockchat client
Info: Using buffer size 255
Info: Trying to connect...
Info: Succeeded to connect
User name: Bob
[192.168.0.3:50453] Alice: Hello Bob!
[192.168.0.4:48678] Bob: Hello Alice!
</pre>
</td>
</tr>
</table>

## License

Licensed under the [ISC License][], see the [`LICENSE`](LICENSE) file.

[ISC License]: https://choosealicense.com/licenses/isc/
