小弟现在做了一个登陆程序,
登陆包设计为:
//包头定义
typedef struct
{
DWORD dwCMD;
DWORD dwLength;//整个数据包的长度 = 数据包的包头 + 数据包的包体
}PACKAGE_HEAD;//登陆包
typedef struct
{
char *Username;
char *password;
} LOGIN_PACKAGE_BODY;//服务器发送给客户端一个登陆回应包,来说明本次登陆是否成功
typedef struct
{
int result;//该值由定义的登陆错误代码,返回给客户端
}LOGIN_PACKAGE_RESP;//完整的数据包的定义
typedef struct
{
PACKAGE_HEAD PACKAGEHEAD;
union
{
LOGIN_PACKAGE_BODY stLogin;
LOGIN_PACKAGE_RESP stLoginResp;
};
}PACKAGE;//客户端
CString str1,str2;
DWORD SendBytes = 0;//发送的字节数目
WSABUF wsabuff;//发送数据的缓冲区
SOCKADDR_IN Addrinfo;
WORD port = 5050;
DWORD dwFlags = 0; //连接服务端
Addrinfo.sin_family = AF_INET;
Addrinfo.sin_addr.s_addr =inet_addr("192.168.1.4");
Addrinfo.sin_port = htons(port); int rc = WSAConnect(m_socket,(sockaddr*)&Addrinfo,sizeof(Addrinfo),NULL,NULL,NULL,NULL); //首先读取两个EDIT框里的数据
GetDlgItem(IDC_EDIT1)->GetWindowText(str1);//获取EDIT1中的数据
GetDlgItem(IDC_EDIT2)->GetWindowText(str2);//获取EDIT2中的数据
PACKAGE sendMsg;//发送给服务端的数据
sendMsg.PACKAGEHEAD.dwCMD = CMD_Login; //包头里的命令
sendMsg.stLogin.Username = str1.GetBuffer (str1.GetLength ());
sendMsg.stLogin.password = str2.GetBuffer (str2.GetLength ());
sendMsg.PACKAGEHEAD.dwLength = sizeof(sendMsg); PACKAGE *p = &sendMsg; wsabuff.buf = (char*)p; wsabuff.len = sizeof(sendMsg);
WSASend(m_socket,&wsabuff,1,&SendBytes,dwFlags,NULL,NULL);服务端代码:
#define SOCKET_BUFF_SIZE 1024
#define DEFAULT_BUFF_SIZE 4096
int rc = 0;
DWORD len = 0;
SOCKET *ps;
char PackageBuff[SOCKET_BUFF_SIZE];//套接字缓冲区
WSABUF DataBuff;
DWORD dwFlags = 0;
char *tempbuff = NULL;
char *Finalbuff = NULL;
char HandleBuff[DEFAULT_BUFF_SIZE];//拼包整理缓冲区
int DataBuffCount = 0;//拼包整理缓冲区里未处理数据的字节数
int StartPos = 0;//要放入拼包数据缓冲区的起始地址 ps = (SOCKET *)lpParam;//工作线程的参数是套接字 while (1)
{
DataBuff.len = SOCKET_BUFF_SIZE; DataBuff.buf = PackageBuff; DWORD RecvBytes = 0; while(RecvBytes < sizeof(PACKAGE_HEAD) )
{ //当收到的数据小于包头,就循环
WSARecv(*ps, &DataBuff, 1,&RecvBytes,&dwFlags,NULL,NULL);
} //将数据拷贝到整理缓冲区尾部
StartPos = DataBuffCount;//获得缓冲区中的起始地址
memcpy(HandleBuff + StartPos,DataBuff.buf,RecvBytes);//将本次接收的数据全部拷贝到整理缓冲区内
DataBuffCount += RecvBytes;//未处理的数据量要增加 //处理包头数据
PACKAGE_HEAD *pHead = new PACKAGE_HEAD ;
memcpy(pHead,HandleBuff,sizeof(PACKAGE_HEAD));//从缓冲区中取得一个包头的长度的数据 //判断拼包整理缓冲区里的数据是否够一个完整的包
if(sizeof(HandleBuff) >= pHead->dwLength )
{ //如果够一个完整的包,则处理该包,处理完毕后要将剩余的数据向前移动
char *tempbuff =(char *) malloc(pHead->dwLength);//分配整个包大小的内存空间
memmove(tempbuff,HandleBuff,pHead->dwLength);//将完整的包体数据存入缓冲区
//包体覆盖包头数据
int ivalue = pHead->dwLength-sizeof(PACKAGE_HEAD); //获得包体的大小
for(int i=0;i<ivalue;i++)
{
tempbuff[i]=tempbuff[i+sizeof(PACKAGE_HEAD)];
} //形成最终的包体数据
char *Finalbuff =(char *) malloc(pHead->dwLength-sizeof(PACKAGE_HEAD));//分配包体大小的内存空间
memcpy(Finalbuff,tempbuff, ivalue );//拷贝包体数据
登陆包设计为:
//包头定义
typedef struct
{
DWORD dwCMD;
DWORD dwLength;//整个数据包的长度 = 数据包的包头 + 数据包的包体
}PACKAGE_HEAD;//登陆包
typedef struct
{
char *Username;
char *password;
} LOGIN_PACKAGE_BODY;//服务器发送给客户端一个登陆回应包,来说明本次登陆是否成功
typedef struct
{
int result;//该值由定义的登陆错误代码,返回给客户端
}LOGIN_PACKAGE_RESP;//完整的数据包的定义
typedef struct
{
PACKAGE_HEAD PACKAGEHEAD;
union
{
LOGIN_PACKAGE_BODY stLogin;
LOGIN_PACKAGE_RESP stLoginResp;
};
}PACKAGE;//客户端
CString str1,str2;
DWORD SendBytes = 0;//发送的字节数目
WSABUF wsabuff;//发送数据的缓冲区
SOCKADDR_IN Addrinfo;
WORD port = 5050;
DWORD dwFlags = 0; //连接服务端
Addrinfo.sin_family = AF_INET;
Addrinfo.sin_addr.s_addr =inet_addr("192.168.1.4");
Addrinfo.sin_port = htons(port); int rc = WSAConnect(m_socket,(sockaddr*)&Addrinfo,sizeof(Addrinfo),NULL,NULL,NULL,NULL); //首先读取两个EDIT框里的数据
GetDlgItem(IDC_EDIT1)->GetWindowText(str1);//获取EDIT1中的数据
GetDlgItem(IDC_EDIT2)->GetWindowText(str2);//获取EDIT2中的数据
PACKAGE sendMsg;//发送给服务端的数据
sendMsg.PACKAGEHEAD.dwCMD = CMD_Login; //包头里的命令
sendMsg.stLogin.Username = str1.GetBuffer (str1.GetLength ());
sendMsg.stLogin.password = str2.GetBuffer (str2.GetLength ());
sendMsg.PACKAGEHEAD.dwLength = sizeof(sendMsg); PACKAGE *p = &sendMsg; wsabuff.buf = (char*)p; wsabuff.len = sizeof(sendMsg);
WSASend(m_socket,&wsabuff,1,&SendBytes,dwFlags,NULL,NULL);服务端代码:
#define SOCKET_BUFF_SIZE 1024
#define DEFAULT_BUFF_SIZE 4096
int rc = 0;
DWORD len = 0;
SOCKET *ps;
char PackageBuff[SOCKET_BUFF_SIZE];//套接字缓冲区
WSABUF DataBuff;
DWORD dwFlags = 0;
char *tempbuff = NULL;
char *Finalbuff = NULL;
char HandleBuff[DEFAULT_BUFF_SIZE];//拼包整理缓冲区
int DataBuffCount = 0;//拼包整理缓冲区里未处理数据的字节数
int StartPos = 0;//要放入拼包数据缓冲区的起始地址 ps = (SOCKET *)lpParam;//工作线程的参数是套接字 while (1)
{
DataBuff.len = SOCKET_BUFF_SIZE; DataBuff.buf = PackageBuff; DWORD RecvBytes = 0; while(RecvBytes < sizeof(PACKAGE_HEAD) )
{ //当收到的数据小于包头,就循环
WSARecv(*ps, &DataBuff, 1,&RecvBytes,&dwFlags,NULL,NULL);
} //将数据拷贝到整理缓冲区尾部
StartPos = DataBuffCount;//获得缓冲区中的起始地址
memcpy(HandleBuff + StartPos,DataBuff.buf,RecvBytes);//将本次接收的数据全部拷贝到整理缓冲区内
DataBuffCount += RecvBytes;//未处理的数据量要增加 //处理包头数据
PACKAGE_HEAD *pHead = new PACKAGE_HEAD ;
memcpy(pHead,HandleBuff,sizeof(PACKAGE_HEAD));//从缓冲区中取得一个包头的长度的数据 //判断拼包整理缓冲区里的数据是否够一个完整的包
if(sizeof(HandleBuff) >= pHead->dwLength )
{ //如果够一个完整的包,则处理该包,处理完毕后要将剩余的数据向前移动
char *tempbuff =(char *) malloc(pHead->dwLength);//分配整个包大小的内存空间
memmove(tempbuff,HandleBuff,pHead->dwLength);//将完整的包体数据存入缓冲区
//包体覆盖包头数据
int ivalue = pHead->dwLength-sizeof(PACKAGE_HEAD); //获得包体的大小
for(int i=0;i<ivalue;i++)
{
tempbuff[i]=tempbuff[i+sizeof(PACKAGE_HEAD)];
} //形成最终的包体数据
char *Finalbuff =(char *) malloc(pHead->dwLength-sizeof(PACKAGE_HEAD));//分配包体大小的内存空间
memcpy(Finalbuff,tempbuff, ivalue );//拷贝包体数据
晕,代码怎么成这个样子了
struct DataPara
{
char ControName[10];
float Data;
};