欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MT7628学习笔记(19)——TCP客户端ipk软件包编写与应用

程序员文章站 2024-02-22 10:22:40
...

基础步骤参考:ipk软件包编写与应用 

一、编写驱动

MT7628学习笔记(19)——TCP客户端ipk软件包编写与应用

 src/net_control_client.c

#include <stdio.h>
#include <stdlib.h>	
#include <unistd.h>	//系统函数
#include <string.h>
#include <pthread.h>	//多线程库

#include "net_control_client.h"

ts_tcp_client s_tcp_client;


static int connect_to_server(void)
{
	while(connect(s_tcp_client.socket_fd, (struct sockaddr *) &(s_tcp_client.server_socket_addr),
			sizeof(struct sockaddr)) != 0){
		//if connect error reconnect after 5 seconds
		perror("connect");
		printf("***reconnect after 5s***\n");
		sleep(5);
		printf("***reconnect...***\n");
	}
	printf("***connected***\n");
#if 1//test message send
	char test_msg[] = "This is from client";
	send(s_tcp_client.socket_fd, test_msg ,sizeof(test_msg),0);
#endif
	return 0;
}

/*
 * 接收socket数据函数.
 * client_fd - 客户端连接的socket。
 */
static int receive_packet(int client_fd)
{
	unsigned char 	buf[TCP_BUFFER_SIZE];
	int		recvbytes;
	while(1){
		/*接收*/
		bzero(buf,sizeof(buf));

		recvbytes = recv(client_fd,buf,TCP_BUFFER_SIZE,0);
		printf("Receive %d bytes\n",recvbytes);

		if (recvbytes <= 0){//receive error or disconnected
			perror("recv");
			/*reconnect to server*/
//			printf("close socket id = %d\n", s_tcp_client.socket_fd);
			close(s_tcp_client.socket_fd);	//关闭通道
			s_tcp_client.socket_fd = socket(AF_INET, SOCK_STREAM, 0);
			if (s_tcp_client.socket_fd == -1){
				perror("socket");
				return -1;
			}
//			printf("new socket id = %d\n", s_tcp_client.socket_fd);
			if (connect_to_server() != 0){
				printf("###connect_to_server error###\n");
				return -1;
			}
		}else{//receive success
#if 1//test
			int i;
			printf("***GET:\n");
			for (i = 0; i < recvbytes; i++){
				printf("0x%02X  %c\n", *(buf+i), *(buf+i));
			}
#endif
		}
	}
	return 0;
}

/*tcp clinet running function*/
int tcp_client_start(void)
{
	printf("***connect to %s.....***\n", s_tcp_client.server_ip);
	/*connect to server*/
	if (connect_to_server() != 0){
		printf("###connect_to_server error###\n");
		return -1;
	}
	receive_packet(s_tcp_client.socket_fd);
	return 0;
}

/*
 * tcp_client initialize function
 * port_num -  TCP server port number
 * server_ip - TCP server ip
 * */
int tcp_client_init(unsigned short port_num, char *server_ip)
{
	int res;
	struct in_addr test_addr;
	/*initialize variable*/
	if (port_num > 0){
		s_tcp_client.server_port = port_num;
	}else{
		printf("###invalid tcp server port:%d###\n", port_num);
		return -1;
	}

	if (server_ip == NULL){
		printf("###server_ip cannot be NULL###\n");
		return -1;
	}else{
		strcpy(s_tcp_client.server_ip, server_ip);//record ip
	}

	/*建立socket描述符*/
	if ((s_tcp_client.socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
		perror("socket");
		return -1;
	}
	printf("socket id = %d\n", s_tcp_client.socket_fd);

	/*
	 * 填充服务器sockaddr结构
	 */
	bzero(&(s_tcp_client.server_socket_addr), sizeof(struct sockaddr_in));	//memset
	s_tcp_client.server_socket_addr.sin_family		 	= AF_INET;
	inet_pton(AF_INET, s_tcp_client.server_ip, &(s_tcp_client.server_socket_addr.sin_addr.s_addr));	//把ip地址转化为用于网络传输的二进制数值
	s_tcp_client.server_socket_addr.sin_port				= htons(s_tcp_client.server_port);	//将主机字节顺序转为网络字节顺序
	bzero(&(s_tcp_client.server_socket_addr.sin_zero), 8);

	return 0;
}

int main(int argc, char *argv[])
{
	int i = 0;
	int res;
	pthread_t 	tcp_thread_id;//返回的线程值
	char tcp_server_port[256];
	char tcp_server_ip[256];

	if (argc >= 2){
		if (strcmp(argv[1],"-v") == 0){
			printf("net_control_client v1.0\n");
			return 0;
		}else if (strcmp(argv[1],"-h") == 0){
			printf("-v for version\n");
			printf("-h for help\n");
			printf("tcp_connect <IP> <port>\n");
			return 0;
		}else if (strcmp(argv[1], "tcp_connect") == 0){
			/*tcp demo*/
			strcpy(tcp_server_ip, argv[2]);
			strcpy(tcp_server_port, argv[3]);

			/*initialize functions*/
			res = tcp_client_init((unsigned short)atoi(tcp_server_port), tcp_server_ip);//set tcp clinet setting
			if (res == -1){
				printf("###tcp_server_init error###\n");
				return -1;
			}

			//create thread for TCP communication
			pthread_create(&tcp_thread_id, NULL, (void *)tcp_client_start, NULL);
		}else{
			printf("Unknown argument %s\n",argv[1]);
			return -1;
		}
	}
	while(1){
		if (i < 100){
			i++;
		}else{
			i = 0;
		}
		sleep(1);
	}
	exit(0);
}

 src/net_control_client.h

#ifndef NET_CONTROL_CLINET_H_
#define NET_CONTROL_CLINET_H_

#include <arpa/inet.h>

#define TCP_BUFFER_SIZE	1024//max buff of receive buffer for tcp

typedef struct{//tcp client class
		unsigned short  	server_port;
		char 				server_ip[64];
		int 				socket_fd;//socket
		struct 				sockaddr_in server_socket_addr;
}ts_tcp_client;



#endif /* NET_CONTROL_CLINET_H_ */

src/Makefile

all:net_control_client

OBJS = net_control_client.o

net_control_client:$(OBJS)
	$(CC) $(CFLAGS) -o aaa@qq.com $(OBJS) -lpthread

clean:
	rm -f net_control_client *.o

Makefile

include $(TOPDIR)/rules.mk#将openwrt顶层目录下的rules.mk文件中的内容导入进来

PKG_NAME:=net_control_client#软件包名
PKG_VERSION:=1.0#软件包版本
PKG_BUILD_DIR:= $(BUILD_DIR)/$(PKG_NAME)#真正编译当前软件包的目录


include $(INCLUDE_DIR)/package.mk#将$(TOPDIR)/include目录下的package.mk文件中的内容导入进来

define Package/net_control_client
	SECTION:=wrtnode#软件包类型
	CATEGORY:=WRTnode#menuconfig中软件包所属的一级目录
	SUBMENU :=demos#menuconfig中软件包所属的二级目录
	TITLE:=net control client -a TCP client#软件包标题
	DEPENDS:=+libpthread#运行本软件依赖的其他包
endef

define Package/net_control_client/description	#软件包描述
	A sample socket net control client
endef

define Build/Prepare	#编译之前的准备动作
	mkdir -p $(PKG_BUILD_DIR)
	$(CP) ./src/* $(PKG_BUILD_DIR)/
endef


define Package/net_control_client/install	#软件包的安装方法,主要就是将一系列编译好的文件、启动脚本、UCI配置文件等拷贝到指定位置
	$(INSTALL_DIR) $(1)/bin
	$(INSTALL_BIN) $(PKG_BUILD_DIR)/net_control_client $(1)/bin/
endef

$(eval $(call BuildPackage,net_control_client))

 

二、选中软件包

MT7628学习笔记(19)——TCP客户端ipk软件包编写与应用

 

三、编译软件包

1、进入 OpenWrt 顶层目录,使用以下命令单独编译软件包:

make package/net_control_client/compile V=s

 

四、软件包发送到开发板并安装:

scp ~/linux/MTK/MT7628/SDK/openwrt-hiwooya/bin/ramips/packages/base/net_control_client_1.0_ramips_24kec.ipk aaa@qq.com:/tmp
opkg install net_control_client_1.0_ramips_24kec.ipk

 MT7628学习笔记(19)——TCP客户端ipk软件包编写与应用

 

五、测试运行软件包

1、连接本地服务器测试::

net_control_client tcp_connect 172.16.2.44 7777

MT7628学习笔记(19)——TCP客户端ipk软件包编写与应用

MT7628学习笔记(19)——TCP客户端ipk软件包编写与应用 

 

2、连接外网服务器测试:

测试服务器地址:http://tcplab.openluat.com/

MT7628学习笔记(19)——TCP客户端ipk软件包编写与应用

MT7628学习笔记(19)——TCP客户端ipk软件包编写与应用

相关标签: OpenWrt