MFC笔记之多线程聊天室

新手刚接触,跟着孙鑫老师视频一步一步的做。从VC6.0到VS2010好像并不是那么顺利,下面记录下一点收获。

网络编程的一般步骤:

1声明套接字版本(WSAStartup);2创建套接字(socket);3绑定套接字(bind);4发送接收(sendto/recvfrom);5关闭(closesocket)

第1~3步代码如下:

 1 CString error;
 2 WORD wver;
 3 wver=MAKEWORD(1,1);
 4 WSAData data;
 5 if(0!=WSAStartup(wver,&data))
 6 {
 7   error.Format(_T("声明版本失败,错误代码:%d!"),WSAGetLastError());
 8   MessageBox(error);
 9 }
10
11 ms=socket(2,SOCK_DGRAM,0);
12 if(ms==INVALID_SOCKET)
13 {
14   error.Format(_T("创建套接字失败,错误代码:%d!"),WSAGetLastError());
15   MessageBox(error);
16 }
17
18 SOCKADDR_IN msaddr;
19 msaddr.sin_family=AF_INET;
20 msaddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
21 msaddr.sin_port=htons(6000);
22 int len=sizeof(msaddr);
23 if(SOCKET_ERROR==bind(ms,(SOCKADDR*)&msaddr,len))
24 {
25   error.Format(_T("绑定套接字失败,错误代码:%d!"),WSAGetLastError());
26   MessageBox(error);
27 }

这段代码要写到OnInitDialog()里;其中ms定义为的SOCKET型成员变量。

既然要用到多线程,这里就先插入一点多线程的知识。

1 HANDLE hThread1;
2 hThread1=CreateThread(NULL,0,fun1pro,(LPVOID)ppr,0,NULL);
3 CloseHandle(hThread1);

其中fun1pro为新线程的入口函数,ppr为传入新线程的参数结构体指针;参数结构体根据需要自行定义。然后是线程函数的实现,里面具体实现socket的接收显示。并且在VS2010中线程函数返回值不能为空,这里我用的DWORD类型;且最好声明成静态成员函数。

 1 DWORD WINAPI CMy0712Dlg::fun1pro(LPVOID lpParameter)
 2     {
 3         SOCKET sock;
 4         HWND hw;
 5         CString error;
 6         sock=((pr*)lpParameter)->s;
 7         hw=((pr*)lpParameter)->hs;
 8         CString cbuf,tbuf;
 9         TCHAR buf[100]={0};
10         TCHAR temp[120]={0};
11         CString ttt,sss;
12         SOCKADDR_IN oaddr;
13         int len=sizeof(SOCKADDR);
14         while (TRUE)
15         { int a=recvfrom(sock,(char*)&buf,100,0,(SOCKADDR*)&oaddr,&len);
16             if(SOCKET_ERROR==a)
17             {
18                 error.Format(_T("接受失败,错误代码:%d!"),WSAGetLastError());
19                 AfxMessageBox(error);
20                 break;
21             }
22             else if(a==0)
23             {
24                 error.Format(_T("socket已经关闭!"));
25                 AfxMessageBox(error);
26                 break;
27             }
28             else
29             {
30                 wsprintf(temp,_T("He said: %s"),buf);
31                 memset(buf,0,100);
32                 sss=_T("");
33                 if(!::PostMessageA(hw,WM_RECV,0,(LPARAM)temp))
34                 {
35                 error.Format(_T("消息传递失败,错误代码:%d!"),GetLastError());
36                 AfxMessageBox(error);
37                 error.GetLength();
38                 }
39             }
40         }
41                 return 0;
42     }

这里将接收到的数据存在了buf里,然后加上格式头存在temp里,通过PostMessage将temp作为自定义消息WM_RECV的lParam传递出去。

这里牵扯到自定义消息的定义

 #define WM_RECV    WM_USER+1

还有消息映射

ON_MESSAGE(WM_RECV,OnRecv)

消息函数的声明实现

 afx_msg LRESULT OnRecv(WPARAM wParam,LPARAM lParam);
 1 LRESULT CMy0712Dlg::OnRecv(WPARAM wParam,LPARAM lParam)
 2 {
 3
 4     CString cs(((TCHAR*)lParam));
 5     CString temp;
 6     GetDlgItemText(IDC_EDIT1,temp);
 7     int i=temp.GetLength();
 8     if(i!=0)
 9     {temp+="\r\n";}
10     temp+=cs;
11     SetDlgItemText(IDC_EDIT1,temp);
12     return 0;
13 }

发送函数做到了一个按钮的响应函数里

 1 void CMy0712Dlg::OnBnClickedButton2()
 2 {
 3     // TODO: 在此添加控件通知处理程序代码
 4     CString cs,error,temp;
 5     SOCKADDR_IN addr;
 6     addr.sin_family=AF_INET;
 7     addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
 8     addr.sin_port=htons(6000);
 9     int len=sizeof(addr);
10     GetDlgItemText(IDC_EDIT2,cs);
11     int i=sendto(ms,(char*)cs.GetBuffer(cs.GetLength()*2),cs.GetLength()*2+2,0,(SOCKADDR*)&addr,sizeof(SOCKADDR));
12     if(SOCKET_ERROR==i)
13     {
14         error.Format(_T("数据发送失败,错误代码:%d!"),WSAGetLastError());
15         MessageBox(error);
16     }
17     cs=_T("");
18     SetDlgItemText(IDC_EDIT2,cs);
19 }

这就基本完成了所有代码,但是在默认使用Unicode字符集的VS2010中还是有点小问题的。其中sendto发送了发送缓存两倍的空间,具体在代码中体现。

参考资料:http://blog.163.com/lj_2005/blog/static/458654220115662544227/

MFC笔记之多线程聊天室

时间: 2024-10-11 11:04:10

MFC笔记之多线程聊天室的相关文章

多线程聊天室

基于Java的多线程聊天室 客户端: public class MultiThreadClient { private static class RecMsg implements Runnable{ private Socket client; public RecMsg(Socket client) { this.client = client; } @Override public void run() { Scanner sc = null; try { sc = new Scanner

Linux下c++11多线程聊天室

刚看的c++11多线程,写个聊天室试试编译的时候加上 c++11 和 多线程库g++ -Wall -std=c++0x -pthread -o server server.cppserver 和client 都是 q 退出?1. [代码]server.cpp #include <iostream>#include <thread>#include <arpa/inet.h>#include <cstring>#include <vector>#i

node.js学习笔记之简洁聊天室

近来刚开始学node.js,基础,深入,express,koa,react,keystone,mongress,等等各种各样的关于Node.js的东西,每个都学的迷迷糊糊的,原因在于没有练习,感觉学的每一个知识点就像一块拼图,最终却没有拼到一起,于是就想多写几个小项目练练手,于是,就有了本文... ----------------------------------我是分割线----------------------------------------------- 恩,就按我写代码的顺序来记

Linux下面基于TCP多线程聊天室(客户端)

不怎么会弄这个博客的排版,就直接将代码附上: 主要是使用多线程去等待接受数据和发送数据,下面是客户端的代码: tcpsed.h文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #ifndef RTPSED_H #define RTPSED_H #define BUFFSIZE 512 int runcond; int socketfd; typedef struct TCP_send_arg { char *tcpserver

Linux下面基于TCP多线程聊天室(服务器)

接上篇博文,本文是服务器端的实现,主要实现的功能,就是现实客户端的连接,转发客户端发送的消息,以及客户端掉线提示等功能,同时可以在这这上面扩展和TCP以及线程相关的功能木块. tcpreceive.h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #ifndef TCPRECEIVE_H #define TCPRECEIVE_H #define BUFFSIZE 2048 #define listen_max 5 int cond; int

Linux以下基于TCP多线程聊天室(server)

接上篇博文,本文是server端的实现,主要实现的功能,就是现实client的连接.转发client发送的消息.以及client掉线提示等功能,同一时候能够在这这上面扩展和TCP以及线程相关的功能木块. tcpreceive.h 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #ifndef TCPRECEIVE_H #define TCPRECEIVE_H #define BUFFSIZE 2048 #define listen_max 5

Java Socket 多线程聊天室

本来这次作业我是想搞个图形界面的,然而现实情况是我把题意理解错了,于是乎失去了最初的兴致,还是把程序变成了功能正确但是“UI”不友好的console了,但是不管怎么样,前期的图形界面的开发还是很有收获的,毕竟讲真,想要把Java搞得有形有色的也是很不容易的,借助可视化的插件windowsBuilder,这个过程还是既exciting 又tiring的. 好吧 ,然而图形界面已经成为了历史,现在来说说这个功能正确的console 吧 我也是刚知道的Eclipse里面是可以跑好多个程序的,只要你的一

Android开发笔记(一百一十一)聊天室中的Socket通信

Socket通信 基本概念 对于程序开发来说,网络通信的基础就是Socket,但因为是基础,所以用起来不容易,今天我们就来谈谈Socket通信.计算机网络有个大名鼎鼎的TCP/IP协议,普通用户在电脑上设置本地连接的ip时,便经常看到下图的弹窗,注意红框部分已经很好地描述了TCP/IP协议的作用. TCP/IP是个协议组,它分为三个层次:网络层.传输层和应用层: 网络层包括:IP协议.ICMP协议.ARP协议.RARP协议和BOOTP协议. 传输层包括:TCP协议.UDP协议. 应用层包括:HT

java多线程控制台聊天室(转)

用java多线程实现一个控制台聊天室,呵呵,好玩! 聊天室服务器端 Java代码   package tf.thread; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.u