IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> Vscode搭建远程c开发环境 -> 正文阅读

[开发工具]Vscode搭建远程c开发环境

基础环境

  • 目标机:ubuntu20
  • 开发机:win10、mac

安装远程开发套件

本机和目标机都需要安装。
请添加图片描述

参考 vscode 免密登录服务器编辑配置服务器信息,用vscode打开远程电脑的一个目录。

建立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
    sleep(1);
	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){
                printf("###socket init error###\n");
				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 send thread*/
int tcp_send_start(void)
{
    char buf[100];
    uint32_t i = 0;

    while(1)
    {
        sleep(5);

        memset(buf,0,sizeof(buf));
        sprintf(buf,"***send data:hello world : %d\n",i);
        i++;
        printf("%s",buf);

        send(s_tcp_client.socket_fd, buf ,strlen(buf),0);
    }


}
/*tcp clinet running function*/
int tcp_client_start(void)
{
    pthread_t 	tcp_send_thread_id;//返回的线程值
	printf("***connect to %s:%d....***\n", s_tcp_client.server_ip,s_tcp_client.server_port);
	/*connect to server*/
	if (connect_to_server() != 0){
		printf("###connect_to_server error###\n");
		return -1;
	}

    
    //create thread for TCP send
	pthread_create(&tcp_send_thread_id, NULL, (void *)tcp_send_start, NULL);

	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
	}
    printf("server ip is: %s\r\n",s_tcp_client.server_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];
    printf("enter main\r\n");
	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;
		}
	}
    else{
        printf("please input ip and port\r\n");
        exit(0);
    }
	while(1){
		if (i < 100){
			i++;
		}else{
			i = 0;
		}
		sleep(1);
	}
	exit(0);
}

.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_ */

配置编译任务

进入 'main.c’文件,然后点击菜单栏 终端->配置默认生成任务,系统会自动建立一个task.json文件,如下

{
	"version": "2.0.0",
	"tasks": [
		{
			"type": "cppbuild",
			"label": "C/C++: gcc 生成活动文件",
			"command": "/usr/bin/gcc",
			"args": [
				"-fdiagnostics-color=always",
				"-g",
				"${file}",
				"-o",
				"${fileDirname}/${fileBasenameNoExtension}",
				"-lpthread"
			],
			"options": {
				"cwd": "${fileDirname}"
			},
			"problemMatcher": [
				"$gcc"
			],
			"group": {
				"kind": "build",
				"isDefault": true
			},
			"detail": "编译器: /usr/bin/gcc"
		}
	]
}

task.json 用来告诉vscode 怎么去编译源文件main.c

  • lablel 定义该任务的名称,后续调试会根据该名称调用本任务,这里名为C/C++: gcc 生成活动文件
  • args :编译时的参数,比如假设程序依赖 pthread库,,那么在这里指定,这里和手动在命令行输入 gcc xxx 命令相同
  • cwd:指定当前运行路径

配置调试程序

仍然保证 编辑区打开的是main.c文件,然后点击菜单栏 运行->添加配置,系统会自动建立一个launch.json文件,如下

{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "gcc - 生成和调试活动文件",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/${fileBasenameNoExtension}",
            "args": ["tcp_connect","192.168.1.201","8888"],//调试时传递给程序的命令行参数 
            "stopAtEntry": true,//是否停留在main函数
            "cwd": "${fileDirname}",//调试程序时的工作目录 
            "environment": [],//环境变量 
            "externalConsole": false,//调试时是否显示控制台窗口 
            "MIMode": "gdb",//指定连接的调试器,可以为gdb或lldb 
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "C/C++: gcc 生成活动文件",//调试开始前执行的任务,一般为编译程序 对应 tasks.json中的label
            "miDebuggerPath": "/usr/bin/gdb"
        }
    ]
}
  • 默认内容和我贴出来的略有不同,我增加了一些参数
  • launch.json 文件用来告诉vscode怎么调用gdb去调试,指定了一些参数,
  • preLaunchTask:调试开始前执行的任务,一般为编译程序 对应 tasks.json中的label
  • stopAtEntry": true,//是否停留在main函数
  • “args”: [“tcp_connect”,“192.168.1.201”,“8888”],//调试时传递给程序的命令行参数 比如我调试这个函数需要在命令行输入,也就是标准输入 输入一些参数,那么填在这里

开始编译

仍然保证 编辑区打开的是main.c文件,

点击菜单栏终端->运行生成任务 或者 ctrl+shift+b

请添加图片描述

开始调试

打开 vscode 侧边栏 选择调试标签

请添加图片描述

观察 绿色三角箭头 右侧的名称,与launch.json中name`一致。

点击绿色箭头,或者按F5 进入调试。

请添加图片描述

注意

在生成配置,或者调试时,一定要保证当前编辑器打开的是待调试的c文件,而不是新建的launch.json或者tasks.json

参考资料

https://code.visualstudio.com/docs/cpp/config-linux

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2021-11-25 08:19:54  更:2021-11-25 08:20:22 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/24 3:25:40-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计