Network programming @ Noppa | @ wiki - Updated: — Jussi Laakkonen 2012/09/10 11:39

Updates:

21.8.2012: Initial draft
04.9.2012: Added link to TCP example code.
10.9.2012: Added a question, hint about IPv6 link locals and nickname length.

Assignment2: TCP multiuser chat with IPv6 support

Second assignment is to implement a chat system that uses TCP-protocol and supports multiple users. One has to implement a client and a server. The basic idea is almost the same as in first assignment but with multiple users that need a centralized server for relaying messages to others. Server listens for connections in one port and when a client connects to this port a new connection is to be established. After that client can send messages to server according to protocol that is described below.

Description

Server must be able to handle multiple connections and detect if client closes connection or connection is lost because of errors in the network for instance. Client needs to establish a connection to server before sending any other data (use connect()-function). Client must register to server with a nickname (limit the length to 15 characters on server) after the connection is established. Client can send messages and requests (change nickname, list users) to server which are processed by server. Messages, introduction messages and nickname changes are forwarded to other connected clients as described in the protocol below. Server must not allow two clients with same nickname, client must be informed if nickname is not allowed. Client can quit at any time and server must inform other connected clients about this event.

Remember to handle messages correctly and use network order for numbers. Note also that when TCP is used messages might not be read as a whole as in UDP, e.g. 40 bytes are sent by client and server receives sent message as separate bytes.

Requirements

Server must not crash if it receives something else than described in the protocol. Same applies for client. Client must inform the user if server is not found or connection is refused. Client must not crash because of the invalid input given by user.

IPv4 and IPv6 must be supported. Use PF_INET6 type socket and allow data from IPv4 mapped addresses although there exists some risks with this. For more details see TLDP.org Linux IPv6 HOWTO 23.1.3.1. IPv4 Mapped Addresses and/or read chapter 4.3 in IPv6 Network Programming book. See also the TCP example code.

Use select() -function in client to check if there are messages either from server or from user input. Remember that fgets() -function is a blocking function that stops reading after receiving a new line marker. Remember to check the input given by user.

Split the code into multiple files based on responsibilities. Think about re-usability of your code, i.e. try to think how to use same functions in both server and client.

Application requirements:

  • Use TCP-protocol for data transfer
  • Sending and receiving messages over TCP
  • Implement client and server
    • Client:
      • Start: ./tcpchatclientserver -h <server address> -p <port number> -n <nickname>
        • User should be able to enter either the IP address or the hostname of the server
      • Commands:
        • <message> - Chat message to server
        • /nick <nickname> - Change nickname
        • /connect <message> - Connect to server with introduction message
        • /who - Request a list of clients from server
        • /quit <message> - Disconnect with quit message
    • Server:
      • Start: /tcpchatclientserver -p <listening port number>
      • Can handle 10 simultaneous users with unique nicknames.
        • Limit nicknames to 15 characters.
      • OPTIONAL: Support any number of users.
      • Server must be iterative (no threads allowed)
      • Commands:
        • /list - List connected clients
        • /stop - Stop accepting new clients (optional)
        • /start - Start accepting new clients (optional)
        • /quit - Shutdown the server

Protocol

Implement following protocol and message structures.

The basic form of each packet is:

32 bit int 16 bit int n characters
packet length packet type packet data

The data portion can be divided into multiple sections, e.g., as in packet type 0. Note that data in packet can be 0 length.

Protocol packets and data types from client to server:

Type 0: connect or change nickname

32 bit int 16 bit int 15 characters n characters
length type nickname introduction message

Action:

  • Server informs other clients on the server that new client connected. The introduction message is forwarded to all except to the newly connected client.
  • If some client wants to change nickname it can send message with this structure and message type containing the new nickname, introduction message is left blank in this case (server should ignore the message when changing nickname).

Type 1: Chat message

32 bit int 16 bit int n characters
length type message

Action:

  • Sent message is forwarded to every client on the server (including the sender!).
  • Do not allow empty messages to be sent or received!

Type 2: request a list of users in the server

32 bit int 16 bit int
length type

Action:

  • Server sends a list of connected clients to client who requested the list.

Type 3: quit

32 bit int 16 bit int n characters
length type quit message

Action:

  • The quitting message sent by leaving client is forwarded to all remaining clients.
  • Server needs to remove the client from its list of clients.

Protocol packets and data types from server to client:

Type 4: forwarded introduction message

32 bit int 16 bit int 15 characters n characters
length type nickname introduction message

Action:

  • Server should forward this message to all.
  • If the client who joined gets this message it means that client is accepted. Do not use this with nickname changes.

Type 5: client changed nickname

32 bit int 16 bit int n characters
length type Nickname change message generated by server

Action:

  • Server should forward this message to all.
  • If the client who changed nickname gets this message it means that change was successful.

Type 6: forwarded chat message

32 bit int 16 bit int 15 characters n characters
length type sender nickname chat message

Action:

  • Chat message that is forwarded to all.
  • Server must keep track of the clients so other clients can be informed about the sender.

Type 7: list of clients

32 bit int 16 bit int n characters
length type list of nicknames separated with NULL characters

Action:

  • Concatenate nicknames to one list and send to client who requested the list.

Type 8: client left

32 bit int 16 bit int 15 characters n characters
length type nickname quit message

Action:

  • Inform remaining clients that someone left.

Type 9: Error message

32 bit int 16 bit int n characters
length type error message

Action:

  • Inform the client that some error has happened (e.g. nickname in use).

Sequence diagrams

Join sequence

Client activities

Additional notes and hints

  • Remember that TCP is stream oriented protocol so the length of the message is required to be known by the receiver.
  • Send numbers (length and type) in network byte-order (see ntohs(), htons(), ntohl() and htonl())
  • Note that there is a maximum for message length.
  • Establish new connections to clients by using accept() -function.
  • Use select() to determine who has sent a message or where it is originating from (stdin or socket).
  • When connecting with link local IPv6 addresses remember to add the scope id (e.g. %eth0) to the address.
  • Pad reserved spaces with NULLs
  • HINTS: accept() connect() send() recv() socket() setsockopt() select() fgets() getaddinfo() freeaddrinfo() listen() bind() socket()

Questions

  • Is there any limit for connection count on the server?
  • What are the three things that limit the amount of different stated connections on the server with TCP?

Network programming @ Noppa | @ wiki