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();
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中,可以使用socket和sendto函数来实现UDP发送功能。具体的发送函数可以根据你的需求来编写,以下是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define SERVER_IP "127.0.0.1" // 服务器IP地址 #define SERVER_PORT 8888 // 服务器端口号 int main() { int sockfd; struct sockaddr_in server_addr; // 创建socket if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(1); } // 设置服务器地址 server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); server_addr.sin_addr.s_addr = inet_addr(SERVER_IP); memset(server_addr.sin_zero, 0, sizeof(server_addr.sin_zero)); // 发送数据 char *message = "Hello, UDP!"; if (sendto(sockfd, message, strlen(message), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("sendto"); exit(1); } // 关闭socket close(sockfd); return 0; } ``` 上述代码中,首先创建了一个UDP socket,并设置服务器的IP地址和端口号。然后通过sendto函数将待发送的数据发送到服务器。最后关闭socket。 请注意,上述代码只是一个简单的示例,实际的发送函数可以根据具体的需求进行修改和扩展。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++socket(udptcp)常用基础函数笔记](https://blog.csdn.net/matrix_studio/article/details/127352149)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [linux C++ UDP通信工具类](https://blog.csdn.net/qq_40778196/article/details/130263498)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值