Impromptu TCP sender/receiver
Some of the logic is nicely encapsulated in functions sendx and recvx, but then main disappoints with its lump of code. It would be better to leave main in charge of parsing and validating the command line arguments, and extract the rest to functions with descriptive names. 

In main the assert(argc == 3) should come before the first memset: no need to initialize memory if you might not use it.

In sendx, the variable i is used for two purposes: loop variable for reading input, and input size. If you extract the input reading to a function that returns the number of characters read, then in sendx you can store that in a variable with a descriptive name, and the logic of the main responsibility of this method will become clearer.