云题海 - 专业文章范例文档资料分享平台

当前位置:首页 > MFC下CSocket编程详解

MFC下CSocket编程详解

  • 62 次阅读
  • 3 次下载
  • 2025/5/3 3:33:37

return 0; }

//绑定端口

if (!aSocket.Bind(nPort)) ...{

char szError[256] = ...{0};

sprintf(szError, \

AfxMessageBox(szError);

return 1; }

3) SDK 下的服务器端代码 //子线程函数

unsigned int StartServer(LPVOID lParam) ...{

//初始化Winsock, AfxSocketInit() 也是封装了这些语句, 不过 AfxSocketInit() 所做的事比这里多些

WSADATA wsaData;

//Winsock 的版本, 建议用1.1 ,兼容性好

WORD wVersionRequested = MAKEWORD(1, 1);

int nResult = WSAStartup(wVersionRequested, &wsaData); if (nResult != 0) ...{

return 1; }

//-----------------------------------------------------

m_exit = false;

CServerDlg *aDlg = (CServerDlg *)lParam;

CString strPort;

aDlg->GetDlgItemText(IDC_EDIT_PORT, strPort);

UINT nPort = atoi(strPort);

//socket------------------------------------------------

//接口对象

SOCKET aSocket, serverSocket;

//寻址相关结构

sockaddr_in serverSockaddr;

memset(&serverSockaddr, 0, sizeof(serverSockaddr));

aSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (aSocket == INVALID_SOCKET) ...{

char szError[256] = ...{0};

sprintf(szError, \

AfxMessageBox(szError);

return 1; }

//注意,该处非常重要,取值的正确与否决定关闭scoket后端口是否能正常释放 BOOL bOptVal = TRUE; int bOptLen = sizeof(BOOL);

//设置 socket 选项, SOL_SOCKET 和 SO_REUSEADDR 一起使用, 并且后面的参数如上,

关闭scoket后端口便能正常释放

setsockopt(aSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&bOptVal, bOptLen);

//寻址相关结构

sockaddr_in aSockaddr;

memset(&aSockaddr,0,sizeof(aSockaddr));

aSockaddr.sin_family = AF_INET;

aSockaddr.sin_addr.s_addr = htonl(INADDR_ANY);

aSockaddr.sin_port = htons((u_short)nPort);

//绑定: 注意参数的类型转换

if(bind(aSocket,(sockaddr *)&aSockaddr, sizeof(aSockaddr)) == SOCKET_ERROR) ...{

char szError[256] = ...{0};

sprintf(szError, \

AfxMessageBox(szError);

return 1; }

//监听

if(listen(aSocket, 10) == SOCKET_ERROR) ...{

char szError[256] = ...{0};

sprintf(szError, \

AfxMessageBox(szError);

return 1; }

CString strText;

aDlg->GetDlgItemText(IDC_EDIT_LOG, strText);

strText += \

aDlg->SetDlgItemText(IDC_EDIT_LOG, strText);

while(!m_exit) ...{

//接收外部连接, 非阻塞

serverSocket = accept(aSocket, (sockaddr *)&serverSockaddr, 0);

if(serverSocket == INVALID_SOCKET) ...{

continue; } else

...{

char szRecvMsg[256] = ...{0}; char szOutMsg[256] = ...{0};

//接收客户端内容: 阻塞

recv(serverSocket, szRecvMsg, 256, 0);

sprintf(szOutMsg, \

aDlg->GetDlgItemText(IDC_EDIT_LOG, strText);

strText += szOutMsg;

aDlg->SetDlgItemText(IDC_EDIT_LOG, strText);

//发送内容给客户端

send(serverSocket, \

//关闭

closesocket(serverSocket); } }

//关闭

closesocket(aSocket); closesocket(serverSocket);

aDlg->GetDlgItemText(IDC_EDIT_LOG, strText);

strText += \

aDlg->SetDlgItemText(IDC_EDIT_LOG, strText);

//当你使用完Winsock接口后,要调用下面的函数对其占用的资源进行释放 WSACleanup();

return 0; }

3. 总结

1) MFC进行编程的确比较简单, 用的代码比较少, 又容易管理。唯一不好的地方在于很多细节上的东西在资料上不容易查出来, 关联性非常紧密, 象 AfxSocketInit() 函数就是,函数的实现里包含着很多不容易理解的类, 并且记录了非常多的环境信息, 比如创建的线程等等,

这样在主线程调用后子线程没有调用执行 CSocket 的操作就会出错。还有就是有些接口的设计非常离奇, 象 CSocket::Create 的接口就是, 实现上还执行了 CSocket::Bind , 非常不容易被发现。并且MSDN上对 CSocket::Bind 的说明又明显的提示需要显示执行 CSocket::Bind 操作。

2) SDK 编程能理解函数的调用顺序和代码的结构就比较容易,省去了MFC下封装了不知道什么东西的部分,使得代码的流程容易控制。但是从上面的例子来看非常明显的并且不是那么容易理解。不仅仅有很多奇怪的结构(微软的命名一直如此, 无所云云), 并且函数相关太过于紧密, 初学者想一下子熟悉使用并不容易, 对开发者来说代码管理起来非常麻烦。

搜索更多关于: MFC下CSocket编程详解 的文档
  • 收藏
  • 违规举报
  • 版权认领
下载文档10.00 元 加入VIP免费下载
推荐下载
本文作者:...

共分享92篇相关文档

文档简介:

return 0; } //绑定端口 if (!aSocket.Bind(nPort)) ...{ char szError[256] = ...{0}; sprintf(szError, \ AfxMessageBox(szError); return 1; } 3) SDK 下的服务器端代码 //子线程函数 unsigned int StartServer(LPVOID lParam) ...{ //初始化Winsock, AfxSocketInit() 也是封装了这些语句, 不过 AfxSocketInit() 所做的事比这里多些 WSADA

× 游客快捷下载通道(下载后可以自由复制和排版)
单篇付费下载
限时特价:10 元/份 原价:20元
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:fanwen365 QQ:370150219
Copyright © 云题海 All Rights Reserved. 苏ICP备16052595号-3 网站地图 客服QQ:370150219 邮箱:370150219@qq.com