MFC socket编程

    新建两个基于对话框的工程,分别为sFile、cFile。在s端添加两个Edit:一个显示窗口IDC_EDIT1(点击右键选择Properties->Styles,选中Multiline,Vertical scroll、Read-only三项),一个输入窗口IDC_EDIT2。然后增加一个发送按钮:IDC_BtnSend。在c端添加三个Edit:一个显示窗口IDC_EDIT1(点击右键选择Properties->Styles,选中Multiline,Vertical scroll、Read-only三项),一个输入窗口IDC_EDIT2,一个IP地址输入窗口IDC_EDIT3。再增加两个按钮:一个发送按钮IDC_SEND,一个连接服务器按钮IDC_btnConnect。

服务器端具体步骤如下:
1、在StdAfx.h中添加 #include <afxsock.h>  // MFC socket extensions
   在Resource.h中添加#define IDP_SOCKETS_INIT_FAILED         103
   在sFileDlg.h中添加public:void update(CString s);
   在sFileDlg.h中添加private:
                             CEdit* show_edit;
                      CEdit* send_edit;
2、在sFileDlg.cpp中添加#include <winsock2.h>(加在#include "stdafx.h"之前)
                       #pragma comment(lib, "WS2_32.lib")
   新建两个socket:SOCKET listen_sock;
                   SOCKET sock;
   声明线程函数  UINT server_thd(LPVOID p);
3、在OnInitDialog()函数中添加:
        show_edit = (CEdit *)GetDlgItem(IDC_EDIT1);
 send_edit = (CEdit *)GetDlgItem(IDC_EDIT2);
 send_edit->SetFocus();

 char name[80];
 CString IP;
 hostent* pHost;
 gethostname(name, 128);//获得主机名
 pHost = gethostbyname(name);//获得主机结构
 IP = inet_ntoa(*(in_addr *)pHost->h_addr);
 update("本机IP地址:" + IP);
 AfxBeginThread(&server_thd, 0);
   添加函数update():
   void CSFileDlg::update(CString s)
{
 show_edit->ReplaceSel(s + "/r/n");
}
  添加线程函数server_thd():
   UINT server_thd(LPVOID p)
{
 WSADATA wsaData;

 WORD wVersion;

 wVersion = MAKEWORD(2,2);

 WSAStartup(wVersion,&wsaData);

// WSAStartup(0x0202, &wsaData);
 SOCKADDR_IN local_addr;
 SOCKADDR_IN client_addr;
 int iaddrSize = sizeof(SOCKADDR_IN);
 int res;
 char msg[1024];
 CSFileDlg * dlg = (CSFileDlg *)AfxGetApp()->GetMainWnd();
 local_addr.sin_family = AF_INET;
 local_addr.sin_port = htons(5150);
 local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 
 if( (listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET )
 {
  dlg->update("创建监听失败");
 }
 if( bind(listen_sock, (struct sockaddr*) &local_addr, sizeof(SOCKADDR_IN)) )
 {
  dlg->update("绑定错误");
 }
 listen(listen_sock, 1);
 if( (sock = accept(listen_sock, (struct sockaddr *)&client_addr, &iaddrSize)) == INVALID_SOCKET)
 {
  dlg->update("accept 失败");
 }
 else
 {
  CString port;
  port.Format("%d", int(ntohs(client_addr.sin_port)));
  dlg->update( "已连接来自:" + CString(inet_ntoa(client_addr.sin_addr)) + "  端口:" +
   port);
 }
 
 接收数据
 while(1)
 {
  if( (res = recv(sock, msg, 1024, 0)) == -1 )
  {
   dlg->update("失去连接");
   break;
  }
  else
  {
   msg[res] = '\0';
   dlg->update("client:" + CString(msg));
  }
 }
 return 0;
}
4、添加按钮实现函数void CSFileDlg::OnBtnSend():
   void CSFileDlg::OnBtnSend()
{
 // TODO: Add your control notification handler code here
 CString s;
 char * msg;
 send_edit->GetWindowText(s);
 msg = s.GetBuffer(s.GetLength());
 if(send(sock, msg, strlen(msg), 0) == SOCKET_ERROR)
 {
  show_edit->ReplaceSel("发送失败/r/n");
 }
 else if(s == "")
 {
  MessageBox("请输入信息");
 }
 else
 {
  show_edit->ReplaceSel("server:" + s + "/r/n");//消息上屏,清空输入,并重获焦点
  send_edit->SetWindowText("");
  send_edit->SetFocus();
 }
}
5、在InitInstance()函数中添加:
   if (!AfxSocketInit())
 {
  AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
  return FALSE;
 }

客户端具体步骤如下:
1、在StdAfx.h中添加 #include <afxsock.h>  // MFC socket extensions
   在Resource.h中添加#define IDP_SOCKETS_INIT_FAILED         103
   在sFileDlg.h中添加public:void update(CString s);
   在sFileDlg.h中添加private:
                      CEdit* edit1;
                      CButton* btnconn;
                             CEdit* send_edit;
                      CEdit* ip_edit;
2、在sFileDlg.cpp中添加#include <winsock2.h>(加在#include "stdafx.h"之前)
                       #pragma comment(lib, "WS2_32.lib")
   新建一个socket:SOCKET sock;
   声明线程函数  UINT recv_thd(LPVOID p);
3、在OnInitDialog()函数中添加:
        edit1 = (CEdit *)GetDlgItem(IDC_EDIT1);
 send_edit = (CEdit *)GetDlgItem(IDC_EDIT2);
 btnconn = (CButton *)GetDlgItem(IDC_btnConnect);
 ip_edit = (CEdit *)GetDlgItem(IDC_EDIT3);

 ip_edit->SetWindowText("127.0.0.1");


   添加函数update():
   void CCFileDlg::update(CString s)
{
 edit1->ReplaceSel(s + "/r/n");
}
  添加线程函数recv_thd():
  UINT recv_thd(LPVOID p)
{
 int res;
 char msg[1024];
 CString s;
 CCFileDlg * dlg = (CCFileDlg *) AfxGetApp()->GetMainWnd();
 dlg->update("in thd");
 
 while(1)
 {
  if( (res = recv(sock, msg, 1024, 0)) == -1)
  {
   dlg->update("失去连接");
   break;
  }
  else
  {
   msg[res] = '/0';
   dlg->update("server:" + CString(msg));
  }
 }
 
 //closesocket(sock);
 return 0;
}
4、添加按钮实现函数void CCFileDlg::OnSend():
   void CCFileDlg::OnSend()
{
 // TODO: Add your control notification handler code here
 CString s;
 char * msg;
 send_edit->GetWindowText(s);
 msg = s.GetBuffer(s.GetLength());
 if(send(sock, msg, strlen(msg), 0) == SOCKET_ERROR)
 {
  update("发送失败");
 }
 else if(s == "")
 {
  MessageBox("请输入信息");
 }
 else
 {
  update("client:" + s);//消息上屏,清空输入,并重获焦点
  send_edit->SetWindowText("");
  send_edit->SetFocus();
 }
}
5、添加连接按钮实现函数OnConnect():
   void CCFileDlg::OnConnect()
{
 // TODO: Add your control notification handler code here
 WSADATA wsaData;
 SOCKADDR_IN server_addr;

 WORD wVersion;

 wVersion = MAKEWORD(2,2);

 WSAStartup(wVersion,&wsaData);

// WSAStartup(0x0202, &wsaData);
 CString ip;
 ip_edit->GetWindowText(ip);//取得服务器的IP地址
 server_addr.sin_addr.s_addr = inet_addr(ip);
 server_addr.sin_family = AF_INET;
 server_addr.sin_port = htons(5150);
 if( (sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
 {
  edit1->ReplaceSel("create socket error/r/n");
 }
 if( connect(sock, (struct sockaddr *) &server_addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
 {
  edit1->ReplaceSel("连接失败/r/n");
 }
 else
 {
  edit1->ReplaceSel("连接成功/r/n");
  AfxBeginThread(&recv_thd, 0);
  btnconn->EnableWindow(FALSE);//按钮变灰
 }
}
6、在InitInstance()函数中添加:
   if (!AfxSocketInit())
 {
  AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
  return FALSE;
 }

 

  • 8
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 26
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值