下面是自己写的一个UDP的对等聊天模型,将客户端与服务器整合到一起,可以用于在局域网内聊天。
基本思想:
在主线程中创建一个线程,在一个约定的端口进行绑定,该线程用于接收并打印聊天信息。在主线程中进行聊天输入处理
具体代码如下:
#include "iostream"
#include <winsock2.h>
#include <Windows.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
#define Const_BufLength 1024
#define Const_Port 12345
BOOL InitServerSocket(void);
BOOL InitClientSocket(void);
WSADATA wsaData;
SOCKET m_socket;
SOCKET m_client_socket;
sockaddr_in SerAdd,CliAdd;
int iLength=sizeof(CliAdd);
int retval;
char strSendMsg[Const_BufLength];
char strRecvMsg[Const_BufLength];
void ReceiveData();
void SendData();
int main()
{
if(!InitServerSocket())
{
cout<<"服务套接字初始化出错,即将退出"<<endl;
WSACleanup();
system("pause");
return -1;
}
if(!InitClientSocket())
{
cout<<"客户套接字初始化出错,即将退出"<<endl;
WSACleanup();
system("pause");
return -1;
}
char ip[20];
cout << "input ip" << endl;
cin >> ip;
CliAdd.sin_addr.s_addr = inet_addr(ip);
HANDLE handle1 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveData, NULL, 0, NULL);
while(1)
{
memset(strSendMsg,0,sizeof(strSendMsg));
cout<<"回复:"<<endl;
cin >> strSendMsg;
if(strcmp(strSendMsg,"exit")==0)
{
strcpy(strSendMsg,"收到客户下线的消息,我是服务器,我也下线了");
retval=sendto(m_socket,strSendMsg,sizeof(strSendMsg),0,(SOCKADDR*)&CliAdd,sizeof(CliAdd));
closesocket(m_socket);
WSACleanup();
return 0;
}
CliAdd.sin_family = AF_INET;
retval=sendto(m_client_socket,strSendMsg,sizeof(strSendMsg),0,(SOCKADDR*)&CliAdd,sizeof(CliAdd));
if(retval==SOCKET_ERROR)
{
cout<<"发送失败,错误ID为:"<<WSAGetLastError()<<endl;
break;
}
else if(retval==0)
{
break;
}
else
{
cout<<"发送成功!"<<endl;
}
}
CloseHandle(handle1);
closesocket(m_socket);
WSACleanup();
return 0;
}
void ReceiveData()
{
sockaddr_in socktmp;
while(1)
{
memset(strRecvMsg,0,sizeof(strRecvMsg));
retval=recvfrom(m_socket,strRecvMsg,Const_BufLength,0,(SOCKADDR*)&socktmp,&iLength);
if(retval==SOCKET_ERROR)
{
cout<<"接受失败,错误ID为:"<<WSAGetLastError()<<endl;
break;
}
else if(retval==0)
{
break;
}
else
{
cout<<"IP:Port/t"<<inet_ntoa(CliAdd.sin_addr)<<":"<<ntohs(CliAdd.sin_port)<<'/t'<<strRecvMsg<<endl;
}
}
}
BOOL InitServerSocket(void)
{
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
cout<<"加载winsock失败,错误ID为:"<<WSAGetLastError()<<endl;
exit(0);
}
m_socket=socket(AF_INET,SOCK_DGRAM,0);
SerAdd.sin_family=AF_INET;
SerAdd.sin_port=htons(Const_Port);
SerAdd.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
int retval;
retval=bind(m_socket,(SOCKADDR*)&SerAdd,sizeof(SOCKADDR));
if(SOCKET_ERROR==retval)
{
closesocket(m_socket);
cout<<"端口绑定失败! 错误ID为:"<<WSAGetLastError()<<endl;
return FALSE;
}
return TRUE;
}
BOOL InitClientSocket(void)
{
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
cout<<"加载winsock失败,错误ID为:"<<WSAGetLastError()<<endl;
exit(0);
}
m_client_socket=socket(AF_INET,SOCK_DGRAM,0);
if(INVALID_SOCKET==m_client_socket)
{
cout<<"套接字创建失败!错误ID为:"<<WSAGetLastError()<<endl;
return FALSE;
}
CliAdd.sin_addr.s_addr = inet_addr("127.0.0.1");
CliAdd.sin_port = htons(12345);
return TRUE;
}