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 run
Since 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 IDusername
: The usernameavatar
: The base64 encoded form of the user's avatar
The UserIdentity body is used as a credential of a specific user:
username
: The usernamepasswd
: The password of the usernewPasswd
: 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 sendertargetid
: The user ID of the recievercontenttype
: The type of content attached to the message, should only contain values amongplaintext
,image
andfile
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 stringfilemd5
: 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 Oruserid
: 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