关于使用协议:笔者写的IM中客户端之间是用udp协议传输即时消息的(如果双方均在线),客户端与服务端之间是使用TCP协议,但由于客户端与服务端双方均要求能够主动向对方发送请求:客户端向服务端主动发送的请求(如登陆,注册,修改等等)、服务端向客户端主动发送的请求(好友添加询问,好友上线下线通知等);由于发送请求都是不定时的,这里要求服务器与客户端都有一个服务套接字,在发送请求之前先进行连接。
关于端口的设定:这里的服务器的服务套接字是事先设定好的(默认为5555),而客户端的客户套接字的端口是随机获取的,设为port1,为了方便起见,我直接将客户端的服务套接字的端口设为(port1+1000),所以如果‘port1+1000’端口被事先占用的话,客户端的服务套接字就会初始化失败,这也是本程序需要改进的一个地方。
开始编程之前,还要解决的是信息包的编码与解码问题,要知道客户端与服务器之间通讯的包有很多种类,例如:登录包,注册包,个人信息修改包,查询好友包等等。。。
每一个包都有一个包头header,用来检验包的正确性以及类型,笔者设计的包头如下:
/*所有信息的头部定义
*
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
*+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*| Magic | | Flags(信息类型) |
*+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
* 信息编号
*
*Magic设为010101,作为检验是否为IM程序包,后面的10位则进行包类型编号
*/
//例如登录包:
typedef struct {//0x5401
char magic;
char flags;
char userid[8];
char password[8];
}cln_log;
//注册包:
typedef struct {//5402
char magic;
char flags;
BYTE sex;
BYTE age;
char name[8];
char pass[8];
char city[8];
char info[20];
}cln_register;