聊天室 利用多线程

//=================================================stdafx.h

struct RECVPARAM

{
SOCKET sock; //已创建的套接字
HWND hwnd; //对话框句柄

};


//=================================================0625CDlg.h 

public:
SOCKET m_socket;

添加InitSocket()自定义函数

BOOL CMy0625CDlg::InitSocket(void)
{
//创建套接字
this->m_socket=::socket(AF_INET,SOCK_DGRAM,0);
//SOCK_DGRAM 数据报类套接字 即UDP

if(INVALID_SOCKET==this->m_socket)
{
::AfxMessageBox("创建套接字失败");
return false;
}
SOCKADDR_IN addrSock; //地址结构体
addrSock.sin_family=AF_INET; //地址族
addrSock.sin_port=::htons(6000); //端口
addrSock.sin_addr.S_un.S_addr=::htonl(INADDR_ANY); //收发本地任意IP

int retval;

//绑定套接字
retval=::bind(this->m_socket,(SOCKADDR*)&addrSock,sizeof(SOCKADDR)); //与指定的IP和端口绑定
if(SOCKET_ERROR==retval)
{
::closesocket(this->m_socket);
::AfxMessageBox("绑定失败");
return FALSE;
}
return TRUE;
}

//在InitDlg()中包含InitSocket()

this->InitSocket();
RECVPARAM* pRecvParam=new RECVPARAM; //RECVPARAM 结构体定义在stdafx.h中
pRecvParam->sock=this->m_socket;
pRecvParam->hwnd=this->m_hWnd;

//创建接收线程
HANDLE hThread=::CreateThread(NULL,0,RecvProc,(LPVOID)pRecvParam,0,NULL);

//关闭该接收线程句柄,释放其引用计数
::CloseHandle(hThread);

//添加线程函数

DWORD WINAPI CMy0625CDlg::RecvProc(LPVOID lpParameter)
{
//获取主线程传递的套接字和窗口句柄
SOCKET sock=((RECVPARAM*)lpParameter)->sock; //取出形参 转化为结构体
HWND hwnd=((RECVPARAM*)lpParameter)->hwnd;
delete lpParameter;

SOCKADDR_IN addrFrom;
int len=sizeof(SOCKADDR);

char recvBuf[200];
char tempBuf[300];

int retval;

while(1)
{
//接收数据
retval=::recvfrom(sock,recvBuf,200,0,(SOCKADDR*)&addrFrom,&len);
if(SOCKET_ERROR==retval)
{
break;
}
::sprintf_s(tempBuf,"%s 说: %s",::inet_ntoa(addrFrom.sin_addr),recvBuf);

//发自定义消息
::PostMessageA(hwnd,WM_RECVDATA,0,(LPARAM)tempBuf); //用lParam来传递字符数组地址
}
return 0;
}


// 自定义消息WM_RECVDATA

#define WM_RECVDATA WM_USER+100

BEGIN_MESSAGE_MAP(CMy0625CDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(WM_RECVDATA, &CMy0625CDlg::OnRecvdata) //此代码是用类精灵生成的
ON_BN_CLICKED(IDOK, &CMy0625CDlg::OnBnClickedOk)
END_MESSAGE_MAP()


afx_msg LRESULT CMy0625CDlg::OnRecvdata(WPARAM wParam, LPARAM lParam)
{
//取出接收到的数据
//::AfxMessageBox("进入收到消息");
CString str=(char*)lParam;
CString strTemp;
//获得已有数据
this->GetDlgItemTextA(IDC_EDIT1,strTemp);
str+="\r\n";
str+=strTemp;
//显示所有接收到的数据
this->SetDlgItemTextA(IDC_EDIT1,str);
return 0;
}


//按下按钮 发出文字聊天

void CMy0625CDlg::OnBnClickedOk()
{
//CDialogEx::OnOK();
//从IP控件中获取对方IP
DWORD dwIP;
( (CIPAddressCtrl*)this->GetDlgItem(IDC_IPADDRESS1) )->GetAddress(dwIP);

SOCKADDR_IN addrTo;
addrTo.sin_family=AF_INET;
addrTo.sin_port=::htons(6000);
addrTo.sin_addr.S_un.S_addr=::htonl(dwIP); //将主机字节顺序转换为网络字节顺序

CString strSend;
this->GetDlgItemTextA(IDC_EDIT2,strSend);
::sendto(this->m_socket,strSend,strSend.GetAllocLength()+1,0,
(SOCKADDR*)&addrTo,sizeof(SOCKADDR));

this->SetDlgItemTextA(IDC_EDIT2,"");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值