Vscode搭建遠(yuǎn)程c開發(fā)環(huán)境的圖文教程
基礎(chǔ)環(huán)境
- 目標(biāo)機(jī):ubuntu20
- 開發(fā)機(jī):win10、mac 安裝
遠(yuǎn)程開發(fā)套件
本機(jī)和目標(biāo)機(jī)都需要安裝。

參考 vscode 免密登錄服務(wù)器編輯配置服務(wù)器信息,用vscode打開遠(yuǎn)程電腦的一個(gè)目錄。
建立c文件
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> //系統(tǒng)函數(shù)
#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數(shù)據(jù)函數(shù).
* 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); //關(guān)閉通道
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);
/*
* 填充服務(wù)器sockaddr結(jié)構(gòu)
*/
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地址轉(zhuǎn)化為用于網(wǎng)絡(luò)傳輸?shù)亩M(jìn)制數(shù)值
s_tcp_client.server_socket_addr.sin_port = htons(s_tcp_client.server_port); //將主機(jī)字節(jié)順序轉(zhuǎn)為網(wǎng)絡(luò)字節(jié)順序
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_ */
配置編譯任務(wù)
進(jìn)入 'main.c'文件,然后點(diǎn)擊菜單欄 終端->配置默認(rèn)生成任務(wù),系統(tǒng)會(huì)自動(dòng)建立一個(gè)task.json文件,如下
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc 生成活動(dòng)文件",
"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 定義該任務(wù)的名稱,后續(xù)調(diào)試會(huì)根據(jù)該名稱調(diào)用本任務(wù),這里名為
C/C++: gcc 生成活動(dòng)文 - args :編譯時(shí)的參數(shù),比如假設(shè)程序依賴
pthread庫,,那么在這里指定,這里和手動(dòng)在命令行輸入 gcc xxx 命令相同 - cwd:指定當(dāng)前運(yùn)行路徑 配置調(diào)試程序
仍然保證 編輯區(qū)打開的是main.c文件,然后點(diǎn)擊菜單欄 運(yùn)行->添加配置,系統(tǒng)會(huì)自動(dòng)建立一個(gè)launch.json文件,如下
{
// 使用 IntelliSense 了解相關(guān)屬性。
// 懸停以查看現(xiàn)有屬性的描述。
// 欲了解更多信息,請?jiān)L問: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "gcc - 生成和調(diào)試活動(dòng)文件",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": ["tcp_connect","192.168.1.201","8888"],//調(diào)試時(shí)傳遞給程序的命令行參數(shù)
"stopAtEntry": true,//是否停留在main函數(shù)
"cwd": "${fileDirname}",//調(diào)試程序時(shí)的工作目錄
"environment": [],//環(huán)境變量
"externalConsole": false,//調(diào)試時(shí)是否顯示控制臺(tái)窗口
"MIMode": "gdb",//指定連接的調(diào)試器,可以為gdb或lldb
"setupCommands": [
{
"description": "為 gdb 啟用整齊打印",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: gcc 生成活動(dòng)文件",//調(diào)試開始前執(zhí)行的任務(wù),一般為編譯程序 對應(yīng) tasks.json中的label
"miDebuggerPath": "/usr/bin/gdb"
}
]
}
- 默認(rèn)內(nèi)容和我貼出來的略有不同,我增加了一些參數(shù)
- launch.json 文件用來告訴vscode怎么調(diào)用gdb去調(diào)試,指定了一些參數(shù),
- preLaunchTask:調(diào)試開始前執(zhí)行的任務(wù),一般為編譯程序 對應(yīng) tasks.json中的label
- stopAtEntry": true,//是否停留在main函數(shù)
- “args”: [“tcp_connect”,“192.168.1.201”,“8888”],//調(diào)試時(shí)傳遞給程序的命令行參數(shù) 比如我調(diào)試這個(gè)函數(shù)需要在命令行輸入,也就是標(biāo)準(zhǔn)輸入 輸入一些參數(shù),那么填在這里
開始編譯
仍然保證 編輯區(qū)打開的是main.c文件,
點(diǎn)擊菜單欄終端->運(yùn)行生成任務(wù) 或者 ctrl+shift+b

開始調(diào)試
打開 vscode 側(cè)邊欄 選擇調(diào)試標(biāo)簽

觀察 綠色三角箭頭 右側(cè)的名稱,與launch.json中name`一致。
點(diǎn)擊綠色箭頭,或者按F5 進(jìn)入調(diào)試。

注意
在生成配置,或者調(diào)試時(shí),一定要保證當(dāng)前編輯器打開的是待調(diào)試的c文件,而不是新建的launch.json或者tasks.json
參考資料
https://code.visualstudio.com/docs/cpp/config-linux
到此這篇關(guān)于Vscode搭建遠(yuǎn)程c開發(fā)環(huán)境的文章就介紹到這了,更多相關(guān)Vscode搭建遠(yuǎn)程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
QT編寫窗口插件實(shí)現(xiàn)調(diào)用窗口的自適應(yīng)
這篇文章主要為大家詳細(xì)介紹了QT編寫窗口插件實(shí)現(xiàn)調(diào)用窗口的自適應(yīng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
C語言詳細(xì)分析講解關(guān)鍵字const與volatile的用法
在C語言中,我們經(jīng)常會(huì)見到const和volatile這兩個(gè)關(guān)鍵字,那么我們今天就來介紹下這兩個(gè)關(guān)鍵字,提起?const?關(guān)鍵字,我們可能首先想到的是經(jīng)過它修飾的變量便是常量了。其實(shí)我們這種想法是錯(cuò)誤的,其實(shí)?const?修飾的變量是只讀的,其本質(zhì)還是變量2022-04-04
C語言數(shù)組和指針,內(nèi)存之間的關(guān)系
這篇文章主要介紹了C語言數(shù)組和指針,內(nèi)存之間的關(guān)系,首先論證一維數(shù)組和一級(jí)指針之前的關(guān)系,我們常常使用一級(jí)指針指針的方式訪問一維數(shù)組,只有對內(nèi)存的理解到位才能理解它們直接的關(guān)系。需要的小伙伴可以參考一下2022-02-02
C語言編程數(shù)據(jù)結(jié)構(gòu)線性表之順序表和鏈表原理分析
本篇文章是C語言編程篇主要為大家介紹了C語言編程中的數(shù)據(jù)結(jié)構(gòu)線性表,文中附含豐富的圖文示例代碼為大家詳解了線性表中的順序表和鏈表,有需要的朋友可以借鑒參考下2021-09-09
C語言數(shù)據(jù)結(jié)構(gòu)順序表中的增刪改(尾插尾刪)教程示例詳解
這篇文章主要為大家介紹了C語言數(shù)據(jù)結(jié)構(gòu)順序表中的增刪改教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2022-02-02

