This is a project of my Computer Internet course a project inspired by my school homework.
Several days before I'm asked to write a project on TCP server-client communication, and I wondered why not build a simple chat service beyond that which would be much more fun?
Therefore here it is, a simple tcp server with several functions which makes it acts like a small chat app.
- User register / login / logout
- Remember login state for device (simple token approach though)
- Send messages via users
- Search users and add contacts (and accept them of course)
- Message sync via different devices
- Send message to offline server (a SMTP-like approach)
- File handling (transfer to and fetch from server)
- To support multilanguage, use base64Encode(utf8.encode(yourMessageHere))before wrapping client messages in json object and sending that to the server (the serve will crash!)
- Always open a new TCP connection to fetch or send file
To clone and run this project in command prompt, do the following under Windows environment with dart SDK configured.
git clone https://github.com/Linloir/Simple-TCP-Server.git
cd Simple-TCP-Server
# [+] In case you want to build an exe
# mkdir build
# dart compile exe ./bin/tcp_server.dart -o ./build/tcp_server.exe
# cd build
# tcp_server.exe [listen port]
dart runSince I was not allowed to base my homework on an existing HTTP protocol, I create my private protocol for this project.
To communicate with the server, your data should conform the following formats:
Every request sent by any client to this server should and should only consist four regions:
- Request length region (4 bytes)
- Payload length region (4 bytes)
- Request JSON (variable length)
- Payload byte stream (variable length)
Each section should interconnect with each other with no byte insets.
The request JSON region is self-explanatory, which contains a encoded JSON string describing the request from the client.
To get use of the JSON object, all you need is the table below describing the supported fields in a JSON object and the possible combinations between them:
| Field | Content | Meaning | 
|---|---|---|
| request | 
 | The type of the request | 
| body | JSON object | The information needed for the request | 
| tokenid | number | null | The identifier of a device | 
The body field of the JSON object is the key part of a request; it contains the key information the server needs to perform the request command.
There are mainly four different types of a body:
The UserInfo body is used to describe the information of an arbitrary user:
- userid: The user ID
- username: The username
- avatar: The base64 encoded form of the user's avatar
The UserIdentity body is used as a credential of a specific user:
- username: The username
- passwd: The password of the user
- newPasswd: The modified password (Should only exists if a user is trying to modify his/hers password)
The Message body is used to describe a message:
- userid: The user ID of the sender
- targetid: The user ID of the reciever
- contenttype: The type of content attached to the message, should only contain values among- plaintext,- imageand- file
- content: The base64encoded utf8encoded string of the original message (Should contain filename if the content type is 'file')
- md5encoded: The calculated md5 value of the encoded content string
- filemd5: The attached file's md5 value (Calculated at client side before sending the request; should only exist if the content type is 'file')
The MessageIdentifier is the identifier for a client to fetch a file for a message, it contains only the necessary part to identify a message:
- msgmd5: The md5 of the message
The UserName or UserID is self-explanatory, which contains only the username of a user in order to search the full info of the user:
- username: The provided username Or- userid: The provided user ID
The usage of different body parts for different request types is described below:
| Request Type | Body Part Contents | 
|---|---|
| STATE | NONE | 
| REGISTER | UserIdentity | 
| LOGIN | UserIdentity | 
| LOGOUT | NONE | 
| SENDMSG | Message | 
| FETCHMSG | NONE | 
| FETCHFILE | MessageIdentifier | 
| SEARCHUSR | UserName | 
| ADDCONTACT | UserID | 
| FETCHCONTACT | NONE | 
The fields of a response JSON is similar to that of a request JSON, excludes for the tokenid field.
The response JSON also offers extra fields to describe the state of a performed command:
| Field | Content | Meaning | 
|---|---|---|
| status | 
 | The completion status of the request | 
| info | String | null | Description of error (Only exists if the status is 'ERR') | 
The body of a response JSON object contains all possible types of a request JSON object, with the addition of two special types below.
The TokenInfo body is self-explanatory, which carries the info of a token. This kind of response body only appears in an extra response preceding the original responsse of the first request from a new client device, which offers the client device a token number:
- tokenid: The allocated token ID
The MessageList body is also self-explanatory, which is a list of Message objects, this kind of response body exists in a FETCHMSG response:
- messages: A list of Message objects