⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clientbysocketdlg.cpp

📁 自己编写的SOCKET程序 源码有详尽的注释 可以用来学习C/S程序的编写方法
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	if (Sock) closesocket(Sock);
	if (Sock_U) closesocket(Sock_U);
	WSACleanup();
	SendMessage(WM_CLOSE);
}

void CClientBySocketDlg::OnGetudpPort(SOCKET s)//请求获得端口号
{
	recv(s, rubsh, sizeof(rubsh), 0);//非常必须,否则用本例的简易方法收到的端口号可能不正确20061123
	if (connected) {
		//清空SOCKET缓冲,用流的方式来实现取得端口及时间等精确控制数据不能依靠SOCKET,
		//只能自己在应用层处理,本程序处理的方式是通过耗尽SOCKET缓冲池(怎么能能算耗尽)
		//的方法来保证一下次所需要数据从第0字节开始,以简单化程序20061122
		//比较可靠的方法是使用XML方式,用<item>conten</item>来标识,但会加大程序处理工作量
		send(s, getUDP, strlen(getUDP) + 1, 0);
		getudp = 1;
	}
}

void CClientBySocketDlg::OnReceiveUDP(SOCKET s)//收UDP包
{
	memset(rubsh, 0, strlen(rubsh));//为什么对方sock没开,也能回收到自己的?Abel.20081202
	CString err_msg = _T("");
	//MsgBoxNUMA(recvfrom(s, rubsh, sizeof(rubsh), 0, (PSOCKADDR)&rmot_udp_addr, &rmot_udp_addr_len));
	//return;
	if (recvfrom(s, rubsh, sizeof(rubsh), 0, (PSOCKADDR)&rmot_udp_addr, &rmot_udp_addr_len) == -1) {
		SendMessage(NETWORK_LOG, LOG_noto_udp, LPARAM(rubsh));//写日志
		return; 
	}
	//if ((rmot_udp_addr.sin_port == serv_udp_addr.sin_port) && (rmot_udp_addr.sin_addr.S_un.S_addr == serv_udp_addr.sin_addr.S_un.S_addr) && !(strcmp(m_udptxt, rubsh))){//判断是否从正确的源头回送的与发送一致的用户报20061122
	if ((rmot_udp_addr.sin_port == serv_udp_addr.sin_port) && (rmot_udp_addr.sin_addr.S_un.S_addr == serv_udp_addr.sin_addr.S_un.S_addr)){//判断是否从正确的源头回送的与发送一致的用户报20061122
		SendMessage(NETWORK_LOG, LOG_recv_udp, LPARAM(rubsh));//写日志
		m_udptxt = rubsh;
	}
	else {
		err_msg = "(被动UDP):";
		err_msg += rubsh;
		SendMessage(NETWORK_LOG, LOG_recv_str, LPARAM(&err_msg));//写日志,写完再继续,函数阻塞,因为err_msg是局变,本例程结束便消失:)20061123
		//recvfrom(CurSock, rubsh, sizeof(rubsh), 0, (PSOCKADDR)&rmot_udp_addr, &rmot_udp_addr_len);
	}
}

void CClientBySocketDlg::OnReceiveTCP(SOCKET s)//收TCP数据
{
	//if (getudp && !gotudp) OnGotudpPort(s);
	//if (gettime) OnGetTime(s);
	//MessageBox("正在计算1");
	UINT uLen = recv(s, recvBufer, sizeof(recvBufer), 0);//清空SOCKET缓冲20061122
	//MessageBox("正在计算2");
	SendMessage(NETWORK_LOG, LOG_recv_cal, LPARAM(recvBufer));
	//MessageBox("正在计算3");
	if (!strcmp(recvBufer, okCut)) { //断开连接
		//send(CurSock, okCut, sizeof(okCut), 0);
		OnClose(s);
		//SendMessage(NETWORK_LOG, LOG_disc_tcp, FindSockNo(ClientSock, CurSock));
		//SendMessage(NETWORK_LOG, LOG_send_tim, FindSockNo(ClientSock, CurSock));
	}
	if (uLen == sizeof(cal_T)) {
		//MessageBox("正在计算4");
		if (((cal_T*)recvBufer)->flag == 'c') {
			char cNum[BUFFER_SIZE];
			sCal_expression.Empty();
			itoa(((cal_T*)recvBufer)->on1, cNum, 10);
			sCal_expression += cNum;
			sCal_expression += ((cal_T*)recvBufer)->op;
			itoa(((cal_T*)recvBufer)->on2, cNum, 10);
			sCal_expression += cNum;
			sCal_expression += ((cal_T*)recvBufer)->equ;
			itoa(((cal_T*)recvBufer)->result, cNum, 10);
			sCal_expression += cNum;
			//MessageBox(sCal_expression);
			SendMessage(NETWORK_LOG, LOG_recv_tcp, LPARAM(&sCal_expression));
			m_result = sCal_expression;
			UpdateData(FALSE);
		}
	}
}

void CClientBySocketDlg::OnGetTime(SOCKET s)//收TCP时间
{
	gettime = 0;
	char* recvData = (char*)malloc(9);
	memset(recvData, 0, 9);
	test = 0;
	recv(s, recvData, 8, 0);
	//recv(Sock, rubsh, sizeof(rubsh), 0);//清空SOCKET缓冲20061122
	test = WSAGetLastError();
	SendMessage(NETWORK_LOG, LOG_recv_tim, LPARAM(recvData));
}

void CClientBySocketDlg::OnGotudpPort(SOCKET s)//获知UDP口号
{
	getudp = 0;//同步互斥变量
	//char recvData[2];
	//recv(s, recvData, sizeof(recvData), 0);
	test = 0;
	test = WSAGetLastError();
	servUDPort = htons(UDP_PORT);
	//memcpy(&servUDPort, &recvData, 2);
	//这其间要显示messagebox,控制权会交给谁?总之,下边如弹出消息框,发回的消息都在这个空隙忙里偷闲处理了:)20061121
	//MessageBox(recvData);
	serv_udp_addr = serv_addr;
	serv_udp_addr.sin_port = servUDPort;
	rmot_udp_addr = serv_udp_addr;
	Sock_U = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	bind(Sock_U, (PSOCKADDR)&addr_in, sizeof(addr_in));
	if (WSAAsyncSelect(Sock_U, m_hWnd, NETWORK_EVENT, FD_WRITE) == SOCKET_ERROR){//对udp先注册:可写准备事件,再作其他处理20061126
		MessageBox("注册UDP网络异步事件失败!");
		closesocket(Sock);
		closesocket(Sock_U);
		return;
	}
	
	SOCKADDR_IN sockAddr;   
	int iLen = sizeof(sockAddr);   
	//getpeername(m_lClient,(struct   sockaddr   *)&sockAddr,&iLen);//得到远程IP地址和端口号   
    
	getsockname(Sock_U, (struct sockaddr*)&sockAddr, &iLen);//得到本地的IP地址和端口号   
	//strAddr = inet_ntoa(sockAddr.sin_addr);//IP   
	//uIPPort = sockAddr.sin_port; //端口号
	
	SendMessage(NETWORK_LOG, LOG_recv_upt, ntohs(sockAddr.sin_port));
	gotudp = 1;
}

void CClientBySocketDlg::OnOperation() 
{
	// TODO: Add your control notification handler code here
	//MsgBoxNUMA(m_oplist.GetCurSel());
	UpdateData(TRUE);//因为后边要送字符到界面,所以先把界面内容取回变量:)20081203
	GetDlgItem(IDC_STATIC_TIME)->EnableWindow(FALSE);
	GetDlgItem(IDC_STATIC_hms)->EnableWindow(FALSE);
	GetDlgItem(IDC_UDPTXT)->EnableWindow(FALSE);
	GetDlgItem(IDC_STATIC_CAL)->EnableWindow(FALSE);
	GetDlgItem(IDC_STATIC_exp)->EnableWindow(FALSE);
	GetDlgItem(IDC_TCP_EXPRESSION)->EnableWindow(FALSE);
	GetDlgItem(IDC_TCPSEND)->EnableWindow(FALSE);
	GetDlgItem(IDC_STATIC_result)->EnableWindow(FALSE);
	GetDlgItem(IDC_TCP_RESULT)->EnableWindow(FALSE);
	
	switch (m_oplist.GetCurSel()) {
		case 0:
			GetDlgItem(IDC_STATIC_TIME)->EnableWindow(TRUE);
			GetDlgItem(IDC_STATIC_hms)->EnableWindow(TRUE);
			GetDlgItem(IDC_UDPTXT)->EnableWindow(TRUE);
			//send(Sock, getTIME, strlen(getTIME) + 1, 0);
			//LOG_send_str
			SendMessage(NETWORK_LOG, LOG_send_str, LPARAM(getTIME));//写日志
			sendto(Sock_U, getTIME, strlen(getTIME), 0, (PSOCKADDR)&serv_udp_addr, sizeof(serv_udp_addr));
			break;
		case 1:
			GetDlgItem(IDC_STATIC_CAL)->EnableWindow(TRUE);
			GetDlgItem(IDC_STATIC_exp)->EnableWindow(TRUE);
			GetDlgItem(IDC_TCP_EXPRESSION)->EnableWindow(TRUE);
			GetDlgItem(IDC_TCPSEND)->EnableWindow(TRUE);
			GetDlgItem(IDC_STATIC_result)->EnableWindow(TRUE);
			GetDlgItem(IDC_TCP_RESULT)->EnableWindow(TRUE);
			sCal_T.equ = '=';
			sCal_T.flag = 'c';
			//sCal_T.result = '?';
			break;
		case 2:
			//GetDlgItem(IDC_OPLIST)->EnableWindow(FALSE);
			//GetDlgItem(IDC_BUTTON1)->EnableWindow(FALSE);
			SendMessage(NETWORK_LOG, LOG_send_itm, LPARAM(cutTCP));//写日志
			send(Sock, cutTCP, strlen(cutTCP), 0);
			break;
		default:
			return;
	}
}

void CClientBySocketDlg::OnTcpsend() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);//因为后边要送字符到界面,所以先把界面内容取回变量:)20081203
	m_expression.TrimLeft();//将开头的空格去除
	m_expression.TrimRight();//将结尾的空格去除
	TrimMid();
	UpdateData(FALSE);
	if (checkExpression()) {
		CString temp = _T("表达式输入有误,请检查!");
		SendMessage(NETWORK_LOG, LOG_loca_log, LPARAM(&temp));//格式不对	
		//MessageBox("格式不对!");
		return;
	}
	//MsgBoxNUMA(m_expression.GetLength());
	//return;
	send(Sock, (char*)&sCal_T, sizeof(sCal_T), 0);
	UpdateData(FALSE);
}

void CClientBySocketDlg::TrimMid()
{
	/*
	for (int i = 0; i < m_expression.GetLength(); i++) {
		if (m_expression.GetAt(i) == ' ') m_expression.SetAt(i, m_expression.GetAt(i + 1));
	}*/
	//UpdateData(FALSE);
	CString temp = _T("");
	for (int i = 0; i < m_expression.GetLength(); i++) {
		if (m_expression.GetAt(i) != ' ') {
			temp += m_expression.GetAt(i);
		}
	}
	m_expression = temp;
}

int CClientBySocketDlg::checkExpression()
{
	char on1 = -1;
	char op = 0;
	char on2 = -1;
	CString temp = _T("");
	CString error = _T("");
	if (m_expression.GetLength() > 9) {
		error = _T("操作数为不大于100的正整数,只支持加减乘三种运算,请按a+b=?格式输入!");
		SendMessage(NETWORK_LOG, LOG_loca_log, LPARAM(&error));//格式不对
		//MessageBox(">9");
		return 1;
	}
	if (m_expression.GetAt(m_expression.GetLength() - 1) != '?') {
		error = _T("请按a+b=?格式输入!");
		SendMessage(NETWORK_LOG, LOG_loca_log, LPARAM(&error));//格式不对
		//MessageBox("!=?");
		return 1;
	}
	for (int i = 0; i < m_expression.GetLength(); i++) {
		if (on1 == -1) {
			//atoi
			if ((m_expression.GetAt(i) >= '0') && (m_expression.GetAt(i) <= '9')) {
				temp += m_expression.GetAt(i);	
			}
			else {
				if (!temp.GetLength()) {
					error = _T("操作数为不大于100的正整数,不能为空,请按a+b=?格式输入!");
					SendMessage(NETWORK_LOG, LOG_loca_log, LPARAM(&error));//格式不对
					//MessageBox("长度不对");
					return 1;
				}
				if ((atoi(temp.GetBuffer(0)) >= 0) && (atoi(temp.GetBuffer(0)) <= 100)) {
					//MsgBoxNUMA(atoi(temp.GetBuffer(0)));
					//MessageBox(temp);
					on1 = atoi(temp.GetBuffer(0));
					sCal_T.on1 = on1;
					temp.Empty();
				}
				else {
					error = _T("第一个操作数大于100,请重新输入!");
					SendMessage(NETWORK_LOG, LOG_loca_log, LPARAM(&error));//格式不对
					//MessageBox("左操作数大于100");
					return 1;
				}
			}
		}
		if ((on1 != -1) && !op) {
			if ((m_expression.GetAt(i) == '+') || (m_expression.GetAt(i) == '-') || (m_expression.GetAt(i) == '*')) {
				op = m_expression.GetAt(i);
				sCal_T.op = op;
				i++;
			}
			else {
				error = _T("只支持加减乘三种运算,请按a+b=?格式输入!");
				SendMessage(NETWORK_LOG, LOG_loca_log, LPARAM(&error));//格式不对
				//MessageBox("格式不对2");
				return 1;
			}
		}
		if ((on1 != -1) && op && (on2 == -1)) {
			if ((m_expression.GetAt(i) >= '0') && (m_expression.GetAt(i) <= '9')) {
				temp += m_expression.GetAt(i);
			}
			else {
				if (!temp.GetLength()) {
					error = _T("操作数为不大于100的正整数,不能为空,请按a+b=?格式输入!");
					SendMessage(NETWORK_LOG, LOG_loca_log, LPARAM(&error));//格式不对
					//MessageBox("格式不对3");
					return 1;
				}
				if ((m_expression.GetAt(i) != '=') || ((m_expression.GetLength() - 2) != i)) {
					error = _T("请按a+b=?格式输入!");
					SendMessage(NETWORK_LOG, LOG_loca_log, LPARAM(&error));//格式不对
					//MessageBox(temp);
					//MsgBoxNUM(m_expression.GetLength());
					//MessageBox("格式不对5");
					return 1;
				}
				else {
					if ((atoi(temp.GetBuffer(0)) >= 0) && ((atoi(temp.GetBuffer(0))) <= 100)) {
						on2 = atoi(temp.GetBuffer(0));
						sCal_T.on2 = on2;
						temp.Empty();
					}
					else {
						error = _T("第二个操作数大于100,请重新输入!");
						SendMessage(NETWORK_LOG, LOG_loca_log, LPARAM(&error));//格式不对
						//MessageBox("右操作数大于100");
						return 1;
					}
				}
			}
		}
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -