MFC Socket网络编程之TCP服务器端


TCP/IP与OSI7层参考模型的对应关系


OSI的第12层也就是物理层数据链路层对应于TCP/IP的网络接口

OSI的第3层网络层对应TCP/IP的网络层

OSI的传输层对应TCP/IP的传输层

OSI的567层也就是会话层,表示层, 应用层对应TCP/IP的应用层

OSI参考模型并不是真正存在的7层;


OSI各层所使用的协议:

应用层:远程登录协议Telnet, 文件传输协议FTP, 超文本传输协议HTTP, 域名服务DNS, 简单右键传输协议SMTP, 邮局协议POP3等;

传输层:传输控制协议TCP, 用户数据包协议UDP;

TCP:面向连接的可靠传输协议;

UDP:无连接的不可靠的传输协议;(发送不管对方是否收到)

网络层:网络协议IP, Internet互联网控制报文协议ICMP, Internet组管理协议IGMP;

在MFC里面编写一个基于TCP的网络聊天程序步骤如下:

服务器端:

1,创建一个基本对话框;

2,向对话框中添加2个编辑框,和1个用来发送数据的按钮,一个发送编辑框, 一个接收消息编辑框, 其中接收消息的编辑框设置如下;

MFC Socket网络编程之TCP服务器端_第1张图片


3,在初始化对话框中添加如下代码,用于在接收编辑框中获得并显示本机的IP地址

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);//服务器线程开始;
	return TRUE;

4.全局线程函数定义

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, 5);//最大用户数
	if ((sock = accept(listen_sock, (struct sockaddr *)&client_addr, &iaddrSize)) == INVALID_SOCKET)
	{
		dlg->update("接收失败!");
	}
	else
	{
		CString port;
		port.Format("%d", int(ntohs(client_addr.sin_port)));
		dlg->update("已连接来自:" + CString(inet_ntoa(client_addr.sin_addr)) + "\n  端口:" +
			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,数据刷新函数update()

void CsFileDlg::update(CString s)
{
	show_edit.ReplaceSel(s + "\r\n");
}

5,发送数据

void CsFileDlg::OnBnClickedBtnsend()
{
	// TODO: 在此添加控件通知处理程序代码
	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();
	}
}
 
  

你可能感兴趣的:(计算机网络,C和C++,Socket,多线程)