MFC实现简单C/S socket聊天程序(含源码、实验报告)

一、问题

掌握socket基于异步消息机制的网络程序设计,掌握windows系统下输入字符unicode宽字符与char字符的转换处理,掌握与SOCKET接口的相关API的功能,掌握网络编程技术的基本方法,实现一个较好的人机界面聊天程序。
程序实现可以基于TCP或UDP协议,实现聊天功能,选择完成语音功能,可以考虑完成视频功能。借鉴其他常见网络程序的协议方法,设计用户协议,实现完成用户管理功能与聊天功能,实验报告中要描述协议设计。可以查资料模仿QQ实现方法尽可能多的增加功能。

二、原理

1、利用WSAASsyncSelect异步消息模型设计基于socket的聊天程序。
2、自定义协议用来控制收发数据包类型,以便对不同类型的消息进行相应的处理。
3、利用MFC实现对聊天程序窗口的UI设计。
4、服务器端通过链表管理多个客户端连接。

三、结果展示

客户端:
在这里插入图片描述

  • 1
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
本文将介绍如何使用MFC Winsock实现基于TCP协议的C/S聊天程序。 1. 创建MFC应用程序 首先,我们需要创建一个MFC应用程序。在创建向导中选择“单文档应用程序”类型,勾选“包MFC的ActiveX控件”和“支持ActiveX控件”,其他选项默认即可。 2. 添加界面元素 在资源视图中添加两个编辑框和一个按钮,用于输入和显示聊天内容,以及发送消息。 3. 编写代码 在Dlg.cpp文件中添加以下代码: 在头文件中添加以下头文件: #include "stdafx.h" #include "Dlg.h" #include "afxdialogex.h" #include <winsock2.h> #pragma comment(lib, "ws2_32.lib") 在OnInitDialog()函数中添加以下代码: WSADATA wsaData; SOCKET ConnectSocket = INVALID_SOCKET; struct addrinfo *result = NULL, *ptr = NULL, hints; int iResult; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { MessageBox(_T("WSAStartup failed with error: %d"), iResult); return FALSE; } ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; // Resolve the server address and port iResult = getaddrinfo(_T("localhost"), _T("27015"), &hints, &result); if ( iResult != 0 ) { MessageBox(_T("getaddrinfo failed with error: %d"), iResult); WSACleanup(); return FALSE; } // Attempt to connect to an address until one succeeds for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) { // Create a SOCKET for connecting to server ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (ConnectSocket == INVALID_SOCKET) { MessageBox(_T("socket failed with error: %ld\n"), WSAGetLastError()); WSACleanup(); return FALSE; } // Connect to server. iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen); if (iResult == SOCKET_ERROR) { closesocket(ConnectSocket); ConnectSocket = INVALID_SOCKET; continue; } break; } freeaddrinfo(result); if (ConnectSocket == INVALID_SOCKET) { MessageBox(_T("Unable to connect to server!")); WSACleanup(); return FALSE; } // Set the mode of the socket to be nonblocking u_long iMode = 1; iResult = ioctlsocket(ConnectSocket, FIONBIO, &iMode); if (iResult == SOCKET_ERROR) { MessageBox(_T("ioctlsocket failed with error: %d"), WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return FALSE; } // Disable Nagle's algorithm char value = 1; setsockopt(ConnectSocket, IPPROTO_TCP, TCP_NODELAY, &value, sizeof(value)); 在OnDestroy()函数中添加以下代码: // shutdown the connection since no more data will be sent iResult = shutdown(ConnectSocket, SD_SEND); if (iResult == SOCKET_ERROR) { MessageBox(_T("shutdown failed with error: %d"), WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return FALSE; } // cleanup closesocket(ConnectSocket); WSACleanup(); 在OnBnClickedButtonSend()函数中添加以下代码: // Send a message CString strMsg; m_edtMsg.GetWindowText(strMsg); char buf[1024]; strcpy_s(buf, CT2A(strMsg.GetBuffer())); iResult = send(ConnectSocket, buf, strlen(buf), 0); if (iResult == SOCKET_ERROR) { MessageBox(_T("send failed with error: %d"), WSAGetLastError()); closesocket(ConnectSocket); WSACleanup(); return FALSE; } m_lstMsg.AddString(strMsg); m_edtMsg.SetWindowText(_T("")); 在OnReceive()函数中添加以下代码: char buf[1024]; int iResult = recv(ConnectSocket, buf, sizeof(buf), 0); if (iResult > 0) { CString strMsg(buf); m_lstMsg.AddString(strMsg); } else if (iResult == 0) { MessageBox(_T("Connection closed")); closesocket(ConnectSocket); WSACleanup(); return FALSE; } else { int err = WSAGetLastError(); if (err != WSAEWOULDBLOCK) { MessageBox(_T("recv failed with error: %d"), err); closesocket(ConnectSocket); WSACleanup(); return FALSE; } } 4. 编译运行 现在我们可以编译运行程序,在输入框中输入消息并点击发送按钮,就可以发送消息到服务器并在列表框中显示。当接收到服务器返回的消息时,也会在列表框中显示。 注意:本程序实现了客户端的代码,需要和服务器端代码配合使用才能实现完整的C/S聊天程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

leisure-ZL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值