c++笔记-tcp和udp接口

标题 内容
编者 炎芯随笔
发布时间 2020年8月26日13:53:31
版本 V-1.0

1.前言

2.TCP

2.1头文件变量及函数声明

	//TCP客户端
	WSADATA wsd;
	SOCKET m_socket;
	SOCKADDR_IN ser_addr;

	SOCKET m_socket_data;
	SOCKADDR_IN m_socket_data_addr;
	
	bool tcp_IF_Connected(SOCKET *m_socket);
	bool tcp_Init(SOCKET *m_socket, int timeOut);
	bool tcp_Bind(const char*ip, const char* port, SOCKADDR_IN *ser_addr);
	bool tcp_Connect(SOCKET m_socket, SOCKADDR_IN ser_addr, char*say);
	void tcp_Disconnect(SOCKET *m_socket, char*say);

2.2.函数接口实现

项目 内容
函数名 tcp_IF_Connected
函数参数 SOCKET *m_socket
功能说明 判断tcp是否连接
使用情况 布尔值
示例 参见如下代码
	bool CNFU_4G_PRODlg::tcp_IF_Connected(SOCKET *m_socket)
	{
    
    
		if (*m_socket)
		{
    
    
			sprintf_s(m_showStr, "已连接成功,请先断开再连接\n");
			showCurLineChar(m_listbox, m_showStr);
			return true;
		}
	
		return false;
	}

项目 内容
函数名 tcp_Init
函数参数 SOCKET *m_socket,int timeOut
功能说明 初始化套接字,设置超时时间
使用情况 布尔值
示例 参见如下代码
	bool CNFU_4G_PRODlg::tcp_Init(SOCKET *m_socket, int timeOut)
	{
    
    
		if (timeOut <=0)
		{
    
    
			return FALSE;
		}
	
		*m_socket = socket(AF_INET, SOCK_STREAM, 0);
		if (*m_socket == INVALID_SOCKET)
		{
    
    
			sprintf_s(m_showStr, "套接字初始化失败");
			showCurLineChar(m_listbox, m_showStr);
			return FALSE;
		}
	
		//设置超时
		setTimeOut(m_socket, timeOut);
		return TRUE;
	}

项目 内容
函数名 tcp_Bind
函数参数 const charip, const char port, SOCKADDR_IN *ser_addr
功能说明 绑定ip和端口号
使用情况 布尔值
示例 参见如下代码
	bool  CNFU_4G_PRODlg::tcp_Bind(const char*ip, const char* port, SOCKADDR_IN *ser_addr)
	{
    
    
		int n_serbAddlen = sizeof(SOCKADDR_IN);
		ser_addr->sin_family = AF_INET;
		ser_addr->sin_addr.S_un.S_addr = inet_addr(ip);
		ser_addr->sin_port = htons(atoi(port));
		return TRUE;
	}

项目 内容
函数名 tcp_Connect
函数参数 SOCKET sock, SOCKADDR_IN ser_addr, char*say
功能说明 创建tcp连接
使用情况 布尔值
示例 参见如下代码
	bool CNFU_4G_PRODlg::tcp_Connect(SOCKET sock, SOCKADDR_IN ser_addr, char*say)
	{
    
    
		int n_serbAddlen = sizeof(SOCKADDR_IN);
		int retValue = ::connect(sock, (SOCKADDR*)&ser_addr, n_serbAddlen);
		if (SOCKET_ERROR == retValue)
		{
    
    
			DWORD err = GetLastError();
			sprintf_s(m_showStr, "连接失败");
			showCurLineChar(m_listbox, m_showStr);
	
			closesocket(sock);
			sock = NULL;
	
			return FALSE;
		}
		
		sprintf_s(m_showStr, "%s:连接成功", say);
		showCurLineChar(m_listbox, m_showStr);
		
		return TRUE;
	}

项目 内容
函数名 tcp_Disconnect
函数参数 SOCKET sock, charsay
功能说明 断开tcp连接
使用情况 布尔值
示例 参见如下代码
	void CNFU_4G_PRODlg::tcp_Disconnect(SOCKET *sock, char*say)
	{
    
    
		if (*sock)
		{
    
    
			closesocket(*sock);
			*sock = NULL;
			sprintf_s(m_showStr, "%s:断开连接",say);
			showCurLineChar(m_listbox, m_showStr);
		}
	}

2.3.数据收发接口

项目 内容
函数名 sendData
函数参数 SOCKET m_socket, char* dataIn, int len
功能说明 发送数据
使用情况 发送的字节数
示例 参见如下代码
	int sendData(SOCKET m_socket, char* dataIn, int len)
	{
    
    
		if (!dataIn || len < 0 || m_socket < 0)
		{
    
    
			return -1;
		}
	
		int send_ret = 0;
		int send_ret_add = 0;
		int send_len = len;
		while ((send_ret = send(m_socket, dataIn + send_ret_add, send_len - send_ret_add, 0)) < (send_len - send_ret_add))
		{
    
    
			if (send_ret < 0)
			{
    
    
				return -2;
			}
			send_ret_add += send_ret;
		}
	
		return send_ret_add;
	}

项目 内容
函数名 recvData
函数参数 SOCKET m_socket, char* dataOUT, unsigned long recv_len
功能说明 接收数据
使用情况 接收的字节数
示例 参见如下代码
	int recvData(SOCKET m_socket, char* dataOUT, unsigned long recv_len)
	{
    
    
		if (recv_len < 0 || m_socket < 0){
    
    
			return -1;
		}
	
		int recv_ret = 0;
		unsigned long recv_ret_add = 0;
	
		char *recvBuf = (char*)malloc(sizeof(char)*recv_len+1);
		if (!recvBuf){
    
    
			TRACE("malloc error\n");
			return -1;
		}
	
		while ( 1 ){
    
    
			recv_ret = recv(m_socket, recvBuf + recv_ret_add, recv_len - recv_ret_add, 0);
			if (recv_ret < 0){
    
    
				//2020年6月17日18:45:30
				if (recv_ret_add > 0)
				{
    
    
					memcpy(dataOUT, recvBuf, sizeof(char)*recv_ret_add);
					free(recvBuf);
					return recv_ret_add;
				}
				free(recvBuf);
				return -2;
			}
			recv_ret_add += recv_ret;
			if (recv_ret_add >= recv_len){
    
    
				break;
			}
		}
	
		if (dataOUT != NULL){
    
    
			memcpy(dataOUT, recvBuf, sizeof(char)*recv_ret_add);
		}
		
		free(recvBuf);
		return recv_ret_add;
	}

3.UDP

3.1头文件变量及函数声明

	bool udp_IF_Connected(SOCKET *m_socket);
	bool udp_Init(SOCKET *sock, int timeOut);
	bool udp_Bind(SOCKET *sock, sockaddr_in *sAddr, char*ip, char* port, bool bind_flas);
	void udp_Disconnect(SOCKET *m_socket, char*say);

3.2 函数接口实现

项目 内容
函数名 udp_IF_Connected
函数参数 SOCKET *sock
功能说明 判断tcp是否连接
使用情况 布尔值
示例 参见如下代码
	bool CNFU_4G_PRODlg::udp_IF_Connected(SOCKET *m_socket)
	{
    
    
		if (*m_socket)
		{
    
    
			sprintf_s(m_showStr, "已连接成功,请先断开再连接\n");
			showCurLineChar(m_listbox, m_showStr);
			return true;
		}
		return false;
	}

项目 内容
函数名 udp_Init
函数参数 SOCKET *sock ,int timeOut
功能说明 初始化udp套接字
使用情况 布尔值
示例 参见如下代码
	bool CNFU_4G_PRODlg::udp_Init(SOCKET *sock,int timeOut)
	{
    
    
		DWORD m_dwErr;
		*sock = socket(AF_INET, SOCK_DGRAM, 0);
		if (INVALID_SOCKET == *sock)
		{
    
    
			m_dwErr = GetLastError();
			AfxMessageBox(_T(" m_sock_adc is INVALID_SOCKET!"));
			return false;
		}
		//设置超时
		setTimeOut(sock, timeOut);
		return true;
	}

项目 内容
函数名 udp_Bind
函数参数 SOCKET *sock ,int timeOut
功能说明 绑定udp套接字
使用情况 布尔值
示例 参见如下代码
	bool CNFU_4G_PRODlg::udp_Bind(SOCKET *sock, sockaddr_in *sAddr, char*ip, char* port, bool bind_flas)
	{
    
    
		DWORD m_dwErr;
		memset((char*)sAddr, 0, sizeof(sockaddr_in));
		sAddr->sin_family = AF_INET;
		sAddr->sin_port = htons(atoi(port));
		sAddr->sin_addr.S_un.S_addr = inet_addr(ip);
	
		if (bind_flas)
		{
    
    
			int ret = ::bind(*sock, (sockaddr*)sAddr, sizeof(sockaddr));
			if (SOCKET_ERROR == ret)
			{
    
    
				m_dwErr = GetLastError();
				AfxMessageBox(_T(" bind false!"));
				return false;
			}
		}
		return true;
	}

项目 内容
函数名 udp_Disconnect
函数参数 SOCKET sock, charsay
功能说明 断开udp套接字
使用情况 布尔值
示例 参见如下代码
	void CNFU_4G_PRODlg::udp_Disconnect(SOCKET *sock, char*say)
	{
    
    
		if (*sock)
		{
    
    
			closesocket(*sock);
			*sock = NULL;
			sprintf_s(m_showStr, "%s:断开连接", say);
			showCurLineChar(m_listbox, m_showStr);
		}
	}

4.心跳示例

4.1.创建线程

m_heartBeat = thread(th_heartBeat, this);

4.2.心跳接口实现

typedef struct stMsgHeartBeat		//心跳请求,原样返回
{
    
    
	int heartBeat;
}stMsgHeartBeat;


int th_heartBeat(void* pparam)
{
    
    
	if (!pparam)
		return -1;

	USES_CONVERSION;
	CNFU_4G_PRODlg *pp = (CNFU_4G_PRODlg*)pparam;
	stMsgHeartBeat msgHearBeat = {
    
     0 };
	int try_times_sleep = 0;
	int ret = 0;
	while (true)
	{
    
    
		while (pp->m_bHbing)
		{
    
    
			if (try_times_sleep == 0)
			{
    
    
				msgHearBeat.heartBeat++;
				msgHearBeat.heartBeat = msgHearBeat.heartBeat % 10;
				send(pp->m_socketHeart, (char*)&msgHearBeat, sizeof(msgHearBeat), 0);
				try_times_sleep = 1;
				ret = recvData(pp->m_socketHeart, (char*)&msgHearBeat, sizeof(stMsgHeartBeat));
				if (ret < 0)
				{
    
    
					sprintf_s(pp->m_showStr, "心跳接收超时");
					showCurLineChar(pp->m_listbox, pp->m_showStr);
					pp->m_bStartRecv130 = false;
					pp->OnBnClickedDisconnect();

					break;
				}
				else if (ret >= 0)
				{
    
    
				//	sprintf_s(pp->m_showStr, "收到心跳:%d", msgHearBeat.heartBeat);
				//	showCurLineChar(pp->m_listbox, pp->m_showStr);
				}
			}
		
			Sleep(1000);
			--try_times_sleep;
			if (pp->time_sleep_flags>0)
			{
    
    
				--pp->time_sleep_flags;
			}
		}
		if (pp->m_flags_IF_exit)
		{
    
    
			break;
		}
		Sleep(10);
	}
	
	return 0;
}

4.3.线程等待退出

if (m_heartBeat.joinable())
	{
    
    
		m_heartBeat.join();
	}

猜你喜欢

转载自blog.csdn.net/qq_40904479/article/details/108238487