关于 UnixDomaiSocket 中 send(; ; ; ) 的第二个参数使用 char *str 的可行性验证

    今天要写的内容是来实验 send( , ,) 中的第二个参数是否可以使用 char *str 指针。

    结论是:可以!

    服务端的代码如下:

/* 2012-06-07 - 代码是在 http://beej.us/guide/bgipc/output/html/multipage/unixsock.html 基础上修改的。原始的代码下载
 * echos.c -- the echo server for echoc.c; demonstrates unix sockets
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "/home/tian/mysocket"

int main(void)
{
	int s, s2, t, len;
	struct sockaddr_un local, remote;
	char str[100];

	if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
		perror("socket");
		exit(1);
	}

	local.sun_family = AF_UNIX;
	strcpy(local.sun_path, SOCK_PATH);
	unlink(local.sun_path);
	len = strlen(local.sun_path) + sizeof(local.sun_family);
	if (bind(s, (struct sockaddr *)&local, len) == -1) {
		perror("bind");
		exit(1);
	}

	if (listen(s, 5) == -1) {
		perror("listen");
		exit(1);
	}

	for(;;) 
	{
		int done, n;
		printf("Waiting for a connection...\n");
		t = sizeof(remote);
		if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) {
			perror("accept");
			exit(1);
		}

		printf("Connected.\n");
		
		do 
		{
			memset(str, 0, sizeof(str));
			n = recv(s2, str, 5, 0);
			if (n < 0) 
			{
				perror("recv");
				break;
			}
			else if (n == 0)
			{
				break;
			}
			
			//
			printf("echo> %s\n", str);
			//
		} while (1);

		close(s2);
	}
	return 0;
}

    服务端执行结果截图:


    客户端代码如下:

/* 2012-06-07 - 代码是在 http://beej.us/guide/bgipc/output/html/multipage/unixsock.html 基础上修改的。原始的代码下载
** echoc.c -- the echo client for echos.c; demonstrates unix sockets
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define SOCK_PATH "/home/tian/mysocket"

int main(void)
{
    int s, t, len;
    struct sockaddr_un remote;

    if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    printf("Trying to connect...\n");

    remote.sun_family = AF_UNIX;
    strcpy(remote.sun_path, SOCK_PATH);
    len = strlen(remote.sun_path) + sizeof(remote.sun_family);
    if (connect(s, (struct sockaddr *)&remote, len) == -1) {
        perror("connect");
        exit(1);
    }

    printf("Connected.\n");

 
    int num = 5;
    char *str = (char*)calloc(5, sizeof(char));  
  
    while(1)
    {
         sprintf(str, "%d", num); //将 num 以10进制格式化到 str
	//
	printf("strlen---%d\n", strlen(str)); // 打印 str 的长度
	//
	if (send(s, str, strlen(str), 0) == -1)
    	{
    	    perror("send");
    	    exit(1);
    	}
    	printf("num---%d\n", num); // 打印 num,以此判断 while() 循环是否正确执行
    	num--;
    	if(num == 0) break;
    }
    if (str != NULL)
    {
        str = NULL;
        free(str);	 // 释放 str 占用的内存空间
    }
    close(s);

    return 0;
}

    客户端执行结果截图:


     根据服务端与客户端执行结果,可以判断出:程序执行正常。

``` // 机械臂逆运动学算法 void kinematics_run(float X, float Y, float Z) { float status,i; for ( i = 0; i >= -90.0; i = i - 0.1) { status = kinematics_analysis(X, Y, Z, i); if (status == 200) break; } delay_ms(3000); //kinematics_move_down(); } float kinematics_analysis(float X, float Y, float Z, float Alpha) { float theta0,theta1,theta2,theta3; float l0,l1,l2,l3; float j1,j2,cj1,cj2; float d0,d1,d2,d3; float len,x,y,z; float C1,C2,C3; char dj_1[16],dj_2[16],dj_3[16],dj_4[16]; C1 = X; C2 = Y; C3 = Z; l0 = 100, // 单位为mm l1 = 108, l2 = 88, l3 = 185; if (X == 0) theta0 = 90; else theta0 = atan(Y/X)*180/PI; // atan算出的是弧度 X = sqrt(X*X + Y*Y); X = X - l3 * cos(Alpha * PI / 180); // 三角函数所传入参数为弧度制 Z = Z - l0 - l3 * sin(Alpha * PI / 180); cj1 = (X*X + Z*Z + l1*l1 - l2*l2) / (2 * l1 * sqrt(X*X + Z*Z)); if (cj1 > 1 || cj1 < -1) return 4; j1 = acos(cj1) * 180 / PI; cj2 = (l1*l1 + l2*l2 - X*X - Z*Z) / (2 * l1 * l2); if (cj2 > 1 || cj2 < -1) return 4; j2 = acos(cj2) * 180 / PI; theta1 = (90 - j1 - atan(Z / X) * 180 / PI); if (theta1 > 135.0 || theta1 < -135.0) return 4; theta2 = 180 - j2; if (theta2 > 45.0 || theta2 < -45.0) return 4; theta3 = 90 - theta1 - theta2 - Alpha; if (theta3 > 135.0 || theta3 < -135.0) return 4; d0 = 1500 + theta0 * 1000 / 135; d1 = 1500 - theta1 * 1000 / 135; d2 = 1500 + theta2 * 1000 / 135; d3 = 1500 - theta3 * 1000 / 135; coordinate.dj_pwm[0] = d0; coordinate.dj_pwm[1] = d1; coordinate.dj_pwm[2] = d2; coordinate.dj_pwm[3] = d3; coordinate.dj_angle[4] = Alpha; len = l1*sin(theta1 * PI / 180) + l2*sin((theta1+theta2) * PI / 180) + l3*sin((theta1+theta2+theta3) * PI / 180); z = l0 + l1*cos(theta1 * PI / 180) + l2*cos((theta1+theta2) * PI / 180) + l3*sin(Alpha * PI / 180); x = len * cos(theta0 * PI / 180); y = len * sin(theta0 * PI / 180); x = ceil(x); y = ceil(y); z = ceil(z); if (x == C1 && y == C2 && z == C3) { sprintf(dj_1,"#000P%04.0fT1500!",d0); sprintf(dj_2,"#001P%04.0fT1500!",d1); sprintf(dj_3,"#002P%04.0fT1500!",d2); sprintf(dj_4,"#003P%04.0fT1500!",d3); zx_uart_send_str((u8 *)dj_1); zx_uart_send_str((u8 *)dj_2); zx_uart_send_str((u8 *)dj_3); zx_uart_send_str((u8 *)dj_4); zx_uart_send_str((u8 *)"#005P1700T1500!"); return 200; } return 0; }```这个在keil5软件控制stm32的逆运动学代码解析和数学原理详细解析
03-14
<think>嗯,用户想用C++ 6.0编写一个自动化脚本来刷英华学堂的网课。首先,我得考虑这个需求是否可行。C++ 6.0比较老旧了,现在可能不太适合做自动化脚本,尤其是网页操作。不过用户可能因为某些原因必须用这个版本,比如学校或公司要求。 接下来,我需要考虑如何用C++实现自动化。通常,自动化网页操作可以用像Selenium这样的工具,但C++ 6.0可能不支持这些现代库。可能需要使用Windows API,比如FindWindow和SendMessage来模拟鼠标键盘操作。不过这样的方法可靠性不高,因为窗口标题或位置一旦变化,脚本就会失效。 然后,用户可能需要示例代码。我得提供一个简单的例子,用WinInet库来发送HTTP请求,模拟登录和点击课程。不过需要注意,英华学堂可能有反爬机制,直接发请求可能被封。另外,处理Cookie和会话也是问题,C++ 6.0在这方面可能不太方便。 还要考虑引用站内的资料。用户提供的引用里有关于WinInet的头文件添加,所以在代码示例里需要包含afxinet.h。另外,Visual C++ 6.0在Windows 11上的配置问题,可能需要提醒用户注意兼容性。 安全问题也很重要,直接处理用户名密码有风险,代码里需要提醒用户不要硬编码敏感信息。此外,法律和学校规定方面,刷课可能违反条款,必须提醒用户谨慎使用。 最后,生成相关问题时要覆盖技术难点、安全优化、替代方案和法律方面,帮助用户全面思考。</think>以下是用C++ 6.0实现基础自动化功能的开发思路及示例代码。需要特别说明:自动化操作在线教育平台可能违反平台使用协议,请务必遵守相关法律法规和学校规定[^1]。 ### 开发思路 1. **网络请求模拟**使用WinInet API发送HTTP请求[^3] 2. **界面自动化**:通过Windows API模拟鼠标/键盘操作 3. **定时任务**:创建Windows计时器实现定时操作 4. **数据解析**使用正则表达式处理网页内容 ### 示例代码框架 ```cpp #include <windows.h> #include <wininet.h> #pragma comment(lib, "wininet.lib") #include <string> // 模拟登录功能 BOOL LoginYHXT(const char* username, const char* password) { HINTERNET hInternet = InternetOpen("YHXTAuto", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); HINTERNET hConnect = InternetConnect(hInternet, "www.yhxt.edu.cn", INTERNET_DEFAULT_HTTPS_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); // 构造POST请求 const char* headers = "Content-Type: application/x-www-form-urlencoded"; HINTERNET hRequest = HttpOpenRequest(hConnect, "POST", "/login", NULL, NULL, NULL, INTERNET_FLAG_SECURE | INTERNET_FLAG_RELOAD, 0); std::string data = "username=" + std::string(username) + "&password=" + std::string(password); BOOL bSend = HttpSendRequest(hRequest, headers, strlen(headers), (LPVOID)data.c_str(), data.length()); // 处理响应... InternetCloseHandle(hRequest); InternetCloseHandle(hConnect); InternetCloseHandle(hInternet); return bSend; } // 模拟视频播放完成 void SimulateVideoPlay(DWORD duration) { HWND hWnd = FindWindow(NULL, "课程播放窗口"); if(hWnd) { SetForegroundWindow(hWnd); Sleep(1000); // 发送空格键开始播放 keybd_event(VK_SPACE, 0, 0, 0); keybd_event(VK_SPACE, 0, KEYEVENTF_KEYUP, 0); Sleep(duration * 1000); } } int main() { if(LoginYHXT("testuser", "testpwd")) { SimulateVideoPlay(1800); // 30分钟课程 } return 0; } ``` ### 注意事项 1. **兼容性问题**:需设置Windows兼容模式运行VC6程序[^4] 2. **安全风险**:避免在代码中硬编码账号密码 3. **可靠性问题**:窗口标题可能动态变化,建议使用窗口类名识别 4. **反自动化机制**:平台可能检测自动化操作频率
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值