Socket通讯编程

深入理解C语言中的Socket编程 阅读详情

一、实验要求

  基于 SOCKET通讯技术,在 Windows 平台下,采用 C语言设计开发一个类似 FTP 的文件服务器、客户端程序。客户端可以上传文件到服务器、可以列表服务器文件、可以下载保存文件。

二、实验环境

  系统:Windows 10
  语言:C语言
  开发工具:Dcv-C++ 5.11

三、浅谈Socket

  看一看百度百科的解释:所谓套接字(Socket),就是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议根进行交互的接口。
  一张图来解释一下(图片源于https://blog.youkuaiyun.com/pashanhu6402/article/details/96428887,这篇文章对Socket讲解的很详细,在此就不再赘述):

四、代码下载

  完整的实验代码可以从https://gitee.com/haaaaaaaaaaaa/SourceCode.git上下载,仓库中还有其他实验代码,感兴趣的话可以看看,文章末尾也附有代码。

五、服务端

1、主要步骤:

  1. socket() 创建一个 Socket
  2. bind()
  3. listen() 监听
  4. accept() 接收连接的请求
  5. 进行会话
  6. close() ,关闭 Socket

2、代码设计

/*
Description:Socket 服务器端编程主要步骤如下:
				1、socket() 创建一个 Socket
    			2、bind()
    			3、listen() 监听
    			4、accept() 接收连接的请求
    			5、进行会话
    			6、close() 关闭 Socket
Version:	Dev-C++ 5.11
Date:		2020/05/01
*/ 

#include <stdio.h>          //Needed for printf()
#include <string.h>         //Needed for memcpy() and strcpy()
#include <winsock2.h>
#include <windows.h>        //Needed for all Winsock stuff
#include <ws2tcpip.h>		//Needed forsocklen_t 
#include <stdlib.h>			//解决程序结果一闪而过 
#include "dirent.h"   		//查询文件名需要 

//-----------------------------------------------------
#define PORT_NUM   			5000      //服务器端口号
#define MAX_LISTEN    		3      	  //最大监听数
#define FILE_NAME_MAX_SIZE	512  	  //文件名最大长度 
#define BUFFER_SIZE         1024*4	  //缓冲区大小 
#define FilePath            "./"	  //文件目录,提供目录中所有文件名给client 

unsigned int        server_s;         //Server socket 标示符
struct sockaddr_in  server_addr;      //Server 地址
unsigned int        client_s;         //Client socket标示符
struct sockaddr_in	client_addr;      //Client Internet address
struct in_addr      client_ip_addr;   //Client IP address
int                 addr_len;         //Internet address length
char                out_buf[BUFFER_SIZE];    // 1024*4-byte 输出缓冲区
char                in_buf[BUFFER_SIZE];     // 1024*4-byte 接收缓冲区

/*初始化,建立Socket */
void SocketInit(){
	// 建立socket
	if((server_s = socket(AF_INET, SOCK_STREAM, 0))<0){
		perror("SocketError");
		exit(1);
	}else{
		printf("Server create socket successfully!\n");
	}
	// 配置socket
	server_addr.sin_family 		= AF_INET;          	// Address family to use
	server_addr.sin_port 		= htons(PORT_NUM);    	// 使用端口号
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY); 	//监听任一IP地址
	//bind函数将socket与本地协议端口绑定 
	bind(server_s,(struct sockaddr *)&server_addr, sizeof(server_addr));
} 

/*开始监听,等待客户端连接 */
void Listen (){
	// 监听连接
	printf("Start listening...\n");
	listen(server_s, MAX_LISTEN);
}

/*接受连接,显示IP和端口*/
void Accept(){
	// 接受连接
	addr_len = sizeof(client_addr);
	if((client_s = accept (server_s, (struct sockaddr *)&client_addr, &addr_len))<0){
		perror("AcceptError");
		exit(1);
	}else{
		printf("Accept successfully!\n");
	}
	memcpy(&client_ip_addr, &client_addr.sin_addr.s_addr, 4);
	//输出一条接收完成的消息
	//inet_ntoa将一个十进制网络字节序转换为点分十进制IP格式的字符串
	printf("Accept completed!!!  IP address of client = %s  port = %d \n", inet_ntoa(client_ip_addr), ntohs(client_addr.sin_port));
}

/*向客户端发送数据*/
void SendToClient(){
	memset(in_buf,'\0',sizeof(in_buf));					//将in_buf清空,用来接收数据 
	socklen_t length = sizeof(client_addr);
    length = recv(client_s, in_buf, sizeof(in_buf), 0); //接收client发送的文件名 
    if (length < 0)
    {
        printf("Server recieve data failed!\n");
        exit(1);
    }
    char file_name[FILE_NAME_MAX_SIZE + 1];				//存放文件名 
	memset(file_name,'\0',sizeof(file_name));			//将file_name清空,用来存放文件名 
	//将接收到的文件名放入file_name
    strncpy(file_name, in_buf,strlen(in_buf) > FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE : strlen(in_buf));
    //文件操作 
    FILE *fp = fopen(file_name, "r");
    if (fp == NULL)
    {
        printf("File:\t%s not found!\n", file_name);
    }
	else
    {
        memset(out_buf,'\0',sizeof(out_buf));			//将out_buf清空,用来存放要发送的数据
        int file_block_length = 0;						//文件长度 
        //将文件数据存入到out_buf,准备发送 
        while( (file_block_length = fread(out_buf, sizeof(char), BUFFER_SIZE, fp)) > 0)
        {
            printf("File length = %d\n", file_block_length);
            // 发送buffer中的字符串到client_s,实际上就是发送给客户端
            if (send(client_s, out_buf, (strlen(out_buf) + 1), 0) < 0)
            {
                printf("Send file:\t%s failed!\n", file_name);
                break;
            }
        	memset(out_buf,'\0',sizeof(out_buf));		//将out_buf清空,以便下次使用 
        }
        fclose(fp);
        printf("File:\t%s transfer finished!\n", file_name);
    }    
} 

/*接收从客户端发送来的数据*/ 
void ReceiveFromClient(){
	char file_name[FILE_NAME_MAX_SIZE + 1];  	//存放文件名 
	memset(file_name,'\0',sizeof(file_name)); 	//将file_name清空,用来存放文件名 
	memset(in_buf,'\0',sizeof(in_buf));			//将in_buf清空,用来接收收到的文件名  
	recv(client_s, in_buf, sizeof(in_buf), 0);	//接收client发送过来的文件名 
	//将接收到的文件名放入file_name 
	strncpy(file_name, in_buf, strlen(in_buf) > BUFFER_SIZE ? BUFFER_SIZE : strlen(in_buf));  
   	//文件操作 
	FILE *fp = fopen(file_name, "w");  
    if (fp == NULL)  
    {  
        printf("File:\t%s Can not open to write!\n", file_name);  
        exit(1);  
    }
	// 从服务器端接收数据到in_buf中     
	memset(in_buf,'\0',sizeof(in_buf));			//将in_buf清空,用来接受数据 
    int length = 0;  
	//接收client发送来的数据 
    while(length = recv(client_s, in_buf, sizeof(in_buf), 0))  
    {  
        if (length < 0)  
        {  
            printf("Recieve data from server failed!\n");  
            break;  
        }  
        //将接收的数据写入文件 
        int write_length = fwrite(in_buf, sizeof(char), length, fp);  
        if (write_length < length)  
        {  
            printf("File:\t%s write failed!\n", file_name);  
            break;  
        }  
        memset(in_buf,'\0',sizeof(in_buf));		//将in_buf清空,以便下次使用 
    }
    fclose(fp); //关闭文件 
	printf("Recieve file:\t %s from client finished!\n", file_name);  
}

/*
发送所有文件名给client以便列表出server所有文件
会找出.和..这种目录,没有办法传输 
*/
void SendFileNameToClient(){
	int i = 0;				//记录文件数目 
	char stop[4]="Stop";	//文件名发送完毕标志 
    DIR *dir = NULL;  
    struct dirent *entry;  
    if((dir = opendir(FilePath))==NULL)  
    {  
      	printf("opendir failed!");  
      //return -1;  
    }
	else //if (entry->d_name[0] != '.') //文件名不是'.'或'..'时,没办法忽略 
    {  
     	while(entry=readdir(dir))  
      	{  
      		i++;
       		printf("File Name%d: %s\n",i,entry->d_name);	//输出文件或者目录的名称
       		memset(out_buf,'\0',sizeof(out_buf));			//将out_buf清空,用来存放要发送的文件名
			//将接收到的文件名放入file_name 
			strncpy(out_buf, entry->d_name, strlen(entry->d_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(entry->d_name)); 
			send(client_s, out_buf, (strlen(out_buf) + 1), 0); 
     	}  
     	closedir(dir);
     	//发送结束标志,文件名全部发送完毕。
		//弊端就是要是文件有以Stop...来命名就会出现BUG 
		send(client_s, stop, (strlen(stop) + 1), 0); 
     }	   
} 
 
/*接收client发送来的功能选择*/
void ReceiveChoiceFromClient(){
	char choice[20];//存放选择,及功能前的数字 
	recv(client_s, choice, sizeof(choice), 0);
	printf("The option received:%s\n",choice);
	if(choice[0]=='1'){
		printf("The option received:%s\tUpload Files\n",choice);
		ReceiveFromClient();
	}
	if(choice[0]=='2'){
		printf("The option received:%s\tSend All Files Name\n",choice);
		SendFileNameToClient();
	}	
	else if(choice[0]=='3'){
		printf("The option received:%s\tDownload Files\n",choice);
		SendToClient();
	}	
	else
		printf("Input Error!\n");
}

//主程序 
int main(){ 
	WORD wVersionRequested = MAKEWORD(1,1);  // Stuff for WSA functions
	WSADATA wsaData;                         // Stuff for WSA functions
	//初始化winsock
	WSAStartup(wVersionRequested, &wsaData);
	while(1)
	{
  		printf("**********************************************************\n");
  		printf("*                         Server                         *\n");
  		printf("**********************************************************\n");
  		printf("*                         Welcome                        *\n");
  		printf("**********************************************************\n");
  		SocketInit(); //初始化socket 
		Listen();
		Accept();
		ReceiveChoiceFromClient();
		//关闭sockets
		closesocket(server_s);
		closesocket(client_s);
	}
	//释放winsock
	WSACleanup();
	//解决程序结果一闪而过
	system("pause"); 
	return 0; 
}

六、客户端

1、主要步骤

  1. socket() 创建一个 Socket
  2. connect() 与服务器连接
  3. 进行会话
  4. close() ,关闭 Socket

2、代码设计

/*
Description:Socket 客户端编程主要步骤如下:
				1、socket() 创建一个 Socket
				2、connect() 与服务器连接
				3、进行会话
				4、close() 关闭 Socket
Version:	Dev-C++ 5.11
Date:		2020/05/01
*/ 

#include <stdio.h>          // Needed for printf()
#include <string.h>         // Needed for memcpy() and strcpy()
#include <windows.h>      	// Needed for all Winsock stuff

//----- Defines --------------
#define PORT_NUM			5000     			//服务器端口号
#define IP_ADDR				"127.0.0.1" 	    //服务器IP 地址(本机)
#define FILE_NAME_MAX_SIZE  512  	        	//文件名最大长度 
#define BUFFER_SIZE         1024*4				//缓冲区大小 

unsigned int        server_s;        			//Server socket descriptor
struct sockaddr_in	server_addr;     			//Server Internet address
char                out_buf[BUFFER_SIZE];    	//1024*4-byte 输出缓冲区
char                in_buf[BUFFER_SIZE];     	//1024*4-byte 接收缓冲区

/*初始化,建立Socket */
void SocketInit(){
	// 建立socket
    if((server_s=socket(AF_INET,SOCK_STREAM,0)) < 0) {
        perror("SocketError");
        exit(1);
    } else {
        printf("Client create socket successfully!\n");
    }
  	// 配置socket,建立连接
  	server_addr.sin_family      = AF_INET;    			// Address family to use
  	server_addr.sin_port        = htons(PORT_NUM);   	//端口号
  	server_addr.sin_addr.s_addr = inet_addr(IP_ADDR); 	// IP 地址
} 

/*和Server建立连接*/
void Connect(){
	//建立连接 
  	printf("Request connection...\n");
	if((connect(server_s, (struct sockaddr *)(&server_addr), sizeof(server_addr))) < 0) {
        perror("ConnectError");							//打印错误信息 
        exit(1);
    } else {
        printf("Connnect successfully!\n");
    }
}

/*接受服务器发送来的文件*/
void ReceiveFromServer(){
	char file_name[FILE_NAME_MAX_SIZE + 1];  	//存放文件名 
	memset(file_name,'\0',sizeof(file_name));	//将file_name清空,用来存放文件名 
    printf("Please input file name on server to download:\t");  
    scanf("%s", file_name);  					//输入文件名 
	//将文件名放入in_buf中 
	strncpy(in_buf, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));  
    // 向服务器发送in_buf中的数据,此时in_buf中存放的是客户端需要下载的文件的名字  
    send(server_s, in_buf, (strlen(in_buf) + 1), 0);  
	//文件操作 
	FILE *fp = fopen(file_name, "w");  
    if (fp == NULL)  
    {  
        printf("File:\t%s Can not open to write!\n", file_name);  
        exit(1);  
    }   
	memset(in_buf,'\0',sizeof(in_buf));			//将in_buf清空,用来接受数据 
    int length = 0;
	// 从服务器端接收文件数据到in_buf中    
    while(length = recv(server_s, in_buf, sizeof(in_buf), 0))  
    {  
        if (length < 0)	//判断是否接收(recv)成功 
        {  
            printf("Recieve data from server failed!\n");  
            break;  
        }  
        int write_length = fwrite(in_buf, sizeof(char), length, fp);//将收到的文件数据写入文件 
        if (write_length < length)  								//判断是否写入成功 
        {  
            printf("File:\t%s write failed!\n", file_name);  
            break;  
        }  
        memset(in_buf,'\0',sizeof(in_buf));							//将in_buf清空,以便下次使用 
    }
    fclose(fp); 													//关闭文件 
	printf("Recieve file:\t %s from server finished!\n", file_name);  
}

/*向服务器端发送文件*/ 
void SendToServer(){
	char file_name[FILE_NAME_MAX_SIZE + 1];   	//存放文件名 
	memset(file_name,'\0',sizeof(file_name));	//将file_name清空,用来存放文件名 
    printf("Please input file name on server to upload:\t");  
    scanf("%s", file_name);
	
	memset(out_buf,'\0',sizeof(out_buf));		//将out_buf清空,用来存放要发送的文件的名字 
	//将文件名放入out_buf,以便发送 
	strncpy(out_buf, file_name, strlen(file_name) > BUFFER_SIZE ? BUFFER_SIZE : strlen(file_name));  
    //文件操作 
    FILE *fp = fopen(file_name, "r");
    if (fp == NULL)
    {
        printf("File:\t%s not found!\n", file_name);
    }
	else
    {
    	// 向服务器发送out_buf中的数据,此时out_buf中存放的是客户端需要上传的文件的名字  
    	send(server_s, out_buf, (strlen(out_buf) + 1), 0); //先将文件名发送给server  
        memset(out_buf,'\0',sizeof(out_buf));	//将out_buf清空,用来存放要发送的数据
        int file_block_length = 0;				//文件长度 
        //将文件里的数据读入到out_buf中 
        while( (file_block_length = fread(out_buf, sizeof(char), BUFFER_SIZE, fp)) > 0)
        {
            printf("File length = %d\n", file_block_length);
            // 发送out_buf中的字符串到server
            if (send(server_s, out_buf, (strlen(out_buf) + 1), 0) < 0)
            {
                printf("Send file:\t%s failed!\n", file_name);
                break;
            }
        	memset(out_buf,'\0',sizeof(out_buf));//将out_buf清空
        }
        fclose(fp);
        printf("File:\t%s transfer finished!\n", file_name);
    }  
} 

/*接收server发来的所有文件名,以便列出文件名列表*/
void ReceiveFileNameFromServer(){
	int i = 0;	//记录文件数目
	while(1){
		i++;
		memset(in_buf,'\0',sizeof(in_buf));			//将in_buf清空,用来接受文件名
		recv(server_s, in_buf, sizeof(in_buf), 0); 
		if(in_buf[0]=='S'&&in_buf[1]=='t'&&in_buf[2]=='o'&&in_buf[3]=='p'){
			break;
		}
		else{
			printf("File Name%d: %s\n",i,in_buf);	//输出文件或者目录的名称
		}	
	}
} 

/*向server发送需要进行的操作*/
void SendChoiceToServer(){
	//发送给server需要进行什么操作 
	printf("Input a number, select the function you need:"); 
	char choice[20];//选择功能前的数字
	scanf("%s",choice); 
	send(server_s,choice,(strlen(choice)+1),0); 
	if(choice[0]=='1')
		SendToServer();
	else if(choice[0]=='2')
		ReceiveFileNameFromServer();
	else if(choice[0]=='3')
		ReceiveFromServer();
	else {
		printf("Input Error!Please input again.\n");
	}		
} 

//===== Main program ======
int main(){
	WORD wVersionRequested = MAKEWORD(1,1);     // Stuff for WSA functions
  	WSADATA wsaData;           					// Stuff for WSA functions
	// 初始化winsock
  	WSAStartup(wVersionRequested, &wsaData);
  	while(1){
  		printf("**********************************************************\n");
  		printf("*                         Client                         *\n");
  		printf("**********************************************************\n");
  		printf("*                         Function List:                 *\n");
  		printf("*                         1、Upload Files                *\n");
  		printf("*                         2、List Files                  *\n");
  		printf("*                         3、Download Files              *\n");
  		printf("**********************************************************\n");
  		//初始化socket
		SocketInit();
		//连接 
		Connect();
		//发送操作选项 
		SendChoiceToServer();
  		// 关闭sockets
  		closesocket(server_s);
	} 
  	// 释放 winsock
  	WSACleanup();
  	return 0;
}

七、运行截图

  文件夹展示:

  初始化:
  列表服务端文件名:
  上传文件和下载文件再次不再展示,选择相应功能前的数字指令均可实现。

八、结语

  实验代码还有很多需要优化处理的地方,感兴趣的话可以尝试一下。若文章有问题,或有更好的思路和想法,欢迎在评论区留言讨论。


声明:
若本人发布的作品涉及版权或存在其他问题,请联系我进行删除。
谢谢浏览!
套接字(Sockets)编程——逆向分析向 在套接字编程中,我们创建套接字,这是一个支持网络请求和响应的端点。一旦连接建立,客户端发送了一条消息,服务器接收到消息后,将其回发给客户端,然后关闭连接。逆向工程师可以使用套接字编程创建客户端和服务器,以模拟和分析未知或专有的网络协议。在逆向工程中,套接字编程可以用于多种目的,尤其是在分析网络协议和通信机制时。常见的客户端-服务器模型,如Web服务器和浏览器,数据库服务器和客户端应用程序,都依赖于进程间通信。逆向工程师可以使用套接字编程来拦截网络通信,分析传输的数据,并可能修改数据包以测试应用程序的响应。 阅读详情

相关推荐

Socket网络编程—简单聊天软件--1、什么是Socket及通讯软件设计思路

.Net平台Socket网络编程:Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 Socket就像现实生活中的电话,人与人之间可以通过电话与对方通信,那么应用程序就通过Socket来进行通信。我们要通过电话联系上对方必须得满足三个要求:1,双方都有电话;2,要联系的一方必须知道对方的电话号码;3,双方都必须连接上总服务器;同样的,两个应用程序之间要实现通信

fulei1107655988的专栏 3846

Socket 编程基础

套接字(socket)是 Linux 下的一种进程间通信机制(socket IPC),在前面的内容中已经给大家提到过,使用 socket IPC 可以使得在不同主机上的应用程序之间进行通信(网络通信),当然也可以是同一台主机上的不同应用程序。socket IPC 通常使用客户端服务器这种模式完成通信,多个客户端可以同时连接到服务器中,与服务器之间完成数据交互。内核向应用层提供了 socket 接口,对于应用程序开发人员来说,我们只需要调用 socket 接口开发自己的应用程序即可!

Bit_Dong的博客 3万+

30、JAVA进阶——Socket编程

一、Socket知识 1. Socket概述 2. Socket通信原理 3. java.net包 二、基于TCP协议的Socket编程 1.Socket类和ServerSocket类 2.使用Socket编程实现登录功能 三、基于UDP协议的Socket编程 1.DatagramPacket类和DatagramSocket类 2.使用Socket编程实现客户咨询

不迁怒,不贰过。小知识,大智慧。 2万+

TCP编程函数和步骤

TCP编程的服务器端一般步骤是1、 创建一个socket,用函数socket();2、 设置socket属性,用函数setsockopt(); * 可选3、 绑定IP地址、端口等信息到socket上,用函数bind();4、 开启监听,用函数listen();5、 接收客户端上来

深度Java 7275

C# 与 Socket 编程:创建即时通讯客户端

Socket 是一种在不同计算机之间进行通信的方法。你可以把它想象成互联网上的邮递员,负责在两台电脑之间传递消息。在 C# 中,我们使用命名空间提供的类来实现 Socket 编程。

java专栏 923

Java实现即时通讯系统:QQ聊天与JDBC/Socket编程

本文还有配套的精品资源,点击获取 简介:本项目通过Java编程实现了一个即时通讯系统,模拟QQ聊天功能,包括消息的发送与接收,头像显示等。基于Java JDBC和Socket编程技术,涉及类与对象、多线程处理、网络通信协议TCP/IP、数据库连接、用户界面设计、消息序列化、安全性措施、并发处理以及错误处理等关键编程概念。此项目不但帮助理解即时通讯系统的构造,还能提升开发者在...

weixin_28949937的博客 1077

socket通讯编程

socket通讯编程 传输层协议。包括传输控制协议TCP和用户数据报文协议UDP。 传输控制协议(TCP)。由于IP 提供非连接型传递服务,因此TCP应为应用程序存取网络创造了条件,使用可靠的面向连接的传输层服务。该协议为建立网际上用户进程之间的对话负责。此外,还确保两个以上进程之间的可靠通信。它所提供的功能如下: 1.监听输入对话建立请求。 2.请求另一网络站点对话。 3.可靠的发送和接收数据...

wqw1672的博客 263

运算放大器测试方法-输入失调电压

由于运放输入回路的不对称性,在输入端将产生一定的误差信号,从而限制运放信号灵敏度。通常用输入失调电压(VOS)、输入失调电流(Ios)和输入偏置电流(IB)表示。运放有四个主要特征:输入失调特征、开环特征、共模特征及输出特征。其放大倍数较大,由于外界的影响,即使运放的输入端产生较小的输入信号,经过放大,在输出端也会产生较大的误差。为能精确测量其性能,一般采用辅助运放进行测试。下面着重讲了运放的主要参数及如何精确测量这些参数。文中DUT代表被测运放,A代表辅助运放。

weixin_46135931的博客 1万+

网络通讯和socket编程

(1)基于流的方式;(2)面向连接;(3)可靠通信方式;(4)在网络情况不佳的时候尽量降低系统由于重传带来的带宽开销;(5)通信连接维护是面向的两个端点的,而不考虑中间网段和节点。为满足TCP协议的这些特点,TCP协议做了以下规定:①数据分片:在发送端对用户数据进行分片,在接收端进行重组,由TCP确定分片的大小并控制分片和重组;②到达确认ACK:接收端接收到分片数据时,根据分片数据序号向发送端发送一个确认;③超时重发:发送方在发送分片时启动超时。

imreallycrazy的专栏 201

DIY便携式PEMF磁脉冲治疗仪:百元成本自制生物物理疗法设备

脉冲电磁场(PEMF)疗法是一种基于生物物理原理的非侵入性技术,它通过特定频率的电磁脉冲作用于细胞层面,影响细胞膜电位和离子通道活动,从而可能调节细胞代谢与功能。其技术价值在于提供了一种物理干预手段,在健康科技和生物黑客领域被探索用于放松、恢复等场景。实现PEMF的核心是通过信号发生与功率放大驱动电磁线圈产生可控磁场。本文以蓝牙音频模块和智能手机App为切入点,详细解析了如何利用低成本电子元件(如DFRobot XY-WRBT模块和漆包线线圈)构建一个可自定义频率的便携式PEMF设备,涵盖了从电路设计、线圈

weixin_31476015的博客 344

DDR5内存ODT模式全解析:5种状态与实战配置指南(附时序图)

本文深入解析DDR5内存的片上终端电阻(ODT)机制,详细阐述了其五种核心状态(终结电阻禁用、RTT_WR、RTT_NOM_RD、RTT_NOM_WR、RTT_PARK)的定义、切换时序与工作原理。通过解读JESD79-5规范中的时序图,并提供基于模式寄存器的实战配置指南与代码示例,帮助硬件工程师和系统开发者优化信号完整性,解决高负载下的稳定性问题,并实现性能与功耗的最佳平衡。

weixin_29221753的博客 561

Socket编程进行远程通讯控制UR5机器人

(1)IP相关基础知识 1.如何查询本机IP 1.利用CMD命令窗口,输入 ipconfig ,会返回本机的IP信息 2.控制面板\网络和 Internet\网络和共享中心->无线网络连接->详细信息 ,也可以查询本机IP信息。 2.如何查询某个IP是否可以被访问 利用CMD窗口,输入 ping targetIP ,targetIP是测试的IP地址 3.127....

少安的砖厂 4949

OTA 升级失败/回滚策略设计:打造安全可靠的双分区/断点续传/签名校验方案

双分区机制(A/B Partitioning)是OTA升级的“保险箱”。简单来说,设备存储分为两个分区:A分区(当前运行)和B分区(备用)。升级时,新固件写入B分区,A分区保持不变。如果升级成功,系统切换到B分区运行;如果失败,设备直接回滚到A分区,完全不受影响。这就像玩游戏存档:你打Boss前存了个档,万一挂了还能读档重来。双分区就是设备的“读档”机制,避免了变砖的尴尬。以Android设备为例,Google从Android 7.0开始强制引入A/B分区机制(Seamless Updates)。

大模型大数据攻城狮的专栏 1230

Socket通讯基本流程|Socket编程模型

(4)开始接受客户端连接【accept】//阻塞线程,同时也需要循环不断接受用户连接。(6)接受【receive】和发送消息【send】//需要循环不断接受用户的消息。(2)绑定IP与port端口,即设置要监听的IP与port【bind()】(5)接受了客户端的连接,生成一个新的Socket对象【通信socket】(2)Connect()连接服务器【IP&端口port】(7)【shutdown()】禁用发送与接收功能。(8)【close()】关闭释放资源。(3)开始监听【listen()】

m0_57656758的博客 800

Unity必学:Protobuf-net预编译实战

本文深入解析Unity项目使用Protobuf-net Precompile的必要性。作为高效跨平台序列化方案,Protobuf-net解决了Unity工程在网络同步、存档系统中的性能瓶颈,特别是针对iOS等AOT平台的兼容问题。通过预编译模式,将运行时反射转为静态代码生成,显著提升移动端性能表现,支持协议平滑升级,已成为大厂项目的标配方案。文章从原理、实践到多平台适配,全面展示了这一"序列化发动机"如何支撑现代Unity项目的数据传输需求。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 494

.Net如何使用Web API实现数据交互?

数据模型代表了要交互的数据结构。例如,假设我们要创建一个简单的图书管理系统,我们可以定义一个Book类作为数据模型。set;set;set;

Code365 257

网络通讯和TCP/IP之socket编程

本文讲解 网络通讯和SOCKET编程,可以到链接处下载实例源码

imreallycrazy的专栏 500

Android AICore的核心组件工作原理解析

AICore通过LoRA实现个性化适配Gemini Nano提供多模态智能Safety Features保障可信运行,构建了端侧AI的完整生态。这种设计不仅让手机等移动设备能处理复杂AI任务(如实时多模态交互),还通过隐私保护机制打破了传统云端AI的数据依赖,为未来“设备即AI基础设施”的愿景奠定了基础。输入触发:用户输入“刚提交了代码,等审核”→ 进入TEE加密处理。Gemini Nano基础生成:通过原始权重W_q生成初始回复候选。LoRA个性化微调:通过A'和B'计算ΔW,更新W_q。

1551

UR机器人Socket通讯包:解锁机器人编程新境界

UR机器人Socket通讯包:解锁机器人编程新境界 去发现同类优质开源项目:https://gitcode.com/ 在现代化的工业生产和自动化领域,UR机器人以其灵活性和强大的编程能力获得了广泛关注。今天,我们将为您详细介绍一款强大的工具——UR机器人Socket通讯包,帮助开发者更高效地与UR机器人进行通讯。 项目介绍 UR机器人Socket通讯包是一款专为UR机器人设计的通讯解决方案。它旨在...

gitblog_06709的博客 608

ARM6818嵌入式视频播放器:硬解加速与Framebuffer渲染实战

嵌入式Linux音视频系统是智能座舱、工业HMI等场景的核心能力,其本质是软硬协同的实时多媒体处理系统。原理上需打通内核驱动(如VPU硬件编解码、FIMD多图层合成)、用户空间框架(GStreamer pipeline定制、SDL2硬件渲染)与应用层同步机制(PTS/HTS双时钟校准)。技术价值在于显著降低CPU负载(硬解可压至15%以下)、提升启动速度(<1.2s首帧)并保障音画同步精度(±3ms级)。典型应用场景包括车载信息娱乐、边缘AI终端及无X11的工控显示设备。本文基于ARM6818平台,深入VP

weixin_32456485的博客 77

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

【Unity网络编程知识】使用Socket实现简单TCP通讯

1)连接远程服务端方式1,BeginConnect和EndConnect。1)等待客户端连入方式1,BeginAccept和EndAccept。2)设置客户端连接的最大数量 , Listen(最大连接数)1)同步发送和接收数据,Send()和Receive()1)连接远程服务端,Connect(ip地址和端口)2) 连接远程服务端方式2,ConnectAsync。2)等待客户端连入方式2, AcceptAsync。1)绑定IP和端口, Bind(ip地址和端口)5)建立连接,Accept返回新套接字。

zhoutao2333的博客 1985

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

基于TCP协议的Socket编程与UDP通讯的实现

在网络通讯中,第一次主动发起通讯的程序被称作客户端(Client)程序,简称客户端,而在第一次通讯中等待连接的程序被称作服务器端(Server)程序,简称服务器。一旦通讯建立,则客户端和服务器端完全一样,没有本质的区别。 “请求-响应”模式: 1. Socket类:发送TCP消息。 2. ServerSocket类:创建服务器。 套接字是一种进程间的数据交换机制。这些进程既可以在同一机器上,也可以在通过网络连接的不同机器上。换句话说,套接字起到通信端点的作用。单个...

qq_42681787的博客 555

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

C Socket编程汇川PLC参数一键修改通讯示例

C# Socket编程汇川PLC参数一键修改通讯示例 去发现同类优质开源项目:https://gitcode.com/ 简介 本仓库包含了一个基于C#语言的socket编程示例,用于实现上位机一键修改PLC参数的功能。本示例支持汇川全系列PLC的Modbus TCP通讯,并提供了TCP、UDP两种socket通讯方式。所有代码均为源码,并包含了清晰的关键代码注释,方便学习与复用。 功能特性 支持...

gitblog_06755的博客 524

【Unity网络编程知识】使用Socket实现简单UDP通讯

6)获取本机EndPoint对象(注意:IPEndPoint继承EndPoint)接收消息方式1,BeginReceiveFrom和EndReceiveFrom。1)绑定IP和端口, Bind(ip地址和端口),绑定的是本机的。发送消息方式1,BeginSendTo和EndSendTo。4)释放连接并关闭socket,先于close调用。3)接受消息,ReceiveFrom。2)发送消息,SendTo。3)获取套接字的协议类型。4)获取套接字的寻址方案。1)套接字的连接状态。2)获取套接字的类型。

zhoutao2333的博客 864

CSocket异步通讯资源文件介绍:深入掌握C Socket异步编程

CSocket异步通讯资源文件介绍:深入掌握C# Socket异步编程 去发现同类优质开源项目:https://gitcode.com/ C# Socket异步通讯资源文件,助您快速掌握C#语言下的Socket编程精髓,实现高效的网络通讯。 项目介绍 在现代软件开发中,网络通讯是不可或缺的一部分。C# Socket异步通讯资源文件正是为了满足这一需求而生。该项目以详尽的教程和丰富的示例代码,向开发...

gitblog_06736的博客 561

c# Socket编程,TCP通讯 可互相发送消息,文件

编号:869656878317306___半旧。c# Socket编程,TCP通讯。可互相发送消息,文件。

m0_67394002的博客 265
上一篇: 基于BP神经网络的手写体识别
下一篇: 采用Java RMI技术,实现对数据库表的封装,远程可以实现增删改查操作
MsLeesSun
博客等级 码龄8年 44粉丝 34原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值