自制即时通信系统:socket网络编程(1)
关于使用协议:笔者写的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 {//0x5401char magic;char flags;char userid[8];char password[8];}cln_log;//注册包:typedef struct {//5402char magic;char flags;BYTE sex;BYTE age;char name[8];char pass[8];char city[8];char info[20];}cln_register;