This cheat sheet highlights the steps required to get a C++ Client/Server program running in TCP and UDP protocols. This article provides a handy pseudo code client/server using network sockets. The cheat sheet itself leaves out the finer details of network programming which are important. I recommend you read the Beej's guide to network programming first and then continue below.
Some of the major functions we use in socket programing listed below with their helpful short descriptions.
send()
recv()
sendto
and recvfrom
explicitly define who to send the data to, and where the data was received. These function are most commonly used for UDP protocols however they can be used for TCP (connected sockets) as well.
A simple step guide to networking with sockets can fall within the following:
accept
or recvfrom
, depending on TCP or UDPFor advanced usage the above can be expanded to say
These are established connections and require you to bind, listen or connect (connect if you are a client, bind and listen otherwise) before you can transfer data.
Setup the protocol then wait and listen to connections from client, and transmit on each connection. Note the steps below is for one connection at a time.
# Create address structure
address a = { IP4, TCP, 2047, localhost }
# Create a new socket, bind it to a port and start listening
socket fd = socket(a)
bind(fd, a)
listen(fd)
while True:
# Accept a new connection, accept is blocking and returns when
# client connects. By accepting we create a temporary socket to
# talk to the client
socket temp = accept(fd)
# Send data, to the client and print the message returned by
# the client
message m = recv(temp)
send(temp, "client said:" + m)
close(temp)
close(fd)
The address
type can be quantified as:
address { type, protocol, port, ipaddress };
Instead of binding to a port and listening for clients we instead connect to the server and start transmitting and/or receiving.
# Create address structure
address a = { IP4, TCP, 2047, "serveraddress.com" }
# Create a new socket and connect to the server on this socket
socket fd = socket(a)
connect(fd);
# While the user keeps typing
while <STDIN> as in:
# Send to the server whatever the user typed
send(fd, in)
# Receive a response from the server and print it
message m = recv(fd);
print (m)
close(fd);
What if the request a client asked for takes time? You don't want other clients to wait for the server to finish with one client at a time. Wouldn't it be better to try to deal with other clients while the server is processing one client?
This is simply achieved by using fork()
post accept()
, so the parent can get back at accepting other clients, while the child forked process can deal with one client at a time. I prefer using threads instead of forking for this kind of thing but we gotta walk before we run.
# Create address structure
address a = { IP4, TCP, 2047, localhost }
# Create a new socket, bind it to a port and start listening
socket fd = socket(a)
bind(fd, a)
listen(fd)
while True:
# Accept a new connection, accept is blocking and returns when
# client connects. By accepting we create a temporary socket to
# talk to the client
socket temp = accept(fd)
# Let the program create a child process to deal with the connection
if fork() == 0:
# Send data, to the client and print the message returned by
# the client
message m = recv(temp)
send(temp, "client said:" + m)
close(temp)
close(fd)
Unlike TCP
protocol, the client and server does not care for established connections and due to this the code changes ever so slightly. Some of our handshake code disappears and instead of using send()
and recv()
we use sendto()
and recvfrom()
. One noticeable difference is that sendto()
explicitly requires the address to which to send data. Where as recvfrom()
takes in an address parameter which holds the address of the client the message was received from.
Unlike TCP, UDP fires data to IP addresses given a port without caring for its arrival. It is best to use UDP when you want faster communication but don't care about delivery or order. As an example I use UDP to transfer video or send robots instructions on their next move.
No connection required, and the protocol must be changed to UDP
# Create address structure
address a = { IP4, UDP, 2047, "serveraddress.com" }
# Create a new socket and connect to the server on this socket
socket fd = socket(a)
# While the user keeps typing
while <STDIN> as in:
# Send to the server whatever the user typed
sendto(fd, in, a)
close(fd)
Here we will receive using recvfrom()
and setting the from
variable which is of type address
.
# Create address structure
address a = { IP4, UDP, 2047, "serveraddress.com" }
# Create a new socket and connect to the server on this socket
socket fd = socket(a)
# While the user keeps typing
while True:
# Listen for packets on socket and update the from with the
# address from which the packets were recieved
address from
message m = recvfrom(fd, from)
# Send the sender back the message recieved
sendto(fd, "gotmessage: " + m, from)
close(fd)
send()
won't necessarily send all packet data, to come around this check the number of bytes sent and if less than the total bytes call another send with the new position, repeat if you come up short again.double
may not be represented in the same format on the client and server, so you can't just pass a double
's byte values across the line and hope they convert correctly. Use library to package built-in types or create your own protocol that understands builtin types in a known manner.select()
or pselect()
so your server can perform actions if there are no connection to the server. Preferably use pselect
, it allows signals to interrupt.p/select
. It is a hell of alot faster.threads
instead of fork