`
miss大为
  • 浏览: 83674 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

socket通信 服务端,客户端

 
阅读更多

CocoaAsyncSocket支持tcp和udp。其中:

  • AsyncSocket类是支持TCP的
  • AsyncUdpSocket是支持UDP的

AsyncSocket是封装了CFSocket和CFSteam的TCP/IP socket网络库。它提供了异步操作,本地cocoa类的基于delegate的完整支持。主要有以下特性:

  • 队列的非阻塞的读和写,而且可选超时。你可以调用它读取和写入,它会当完成后告知你自动的socket接收。如果你调用它接收连接,它将为每个连接启动新的实例,当然,也可以立即关闭这些连接委托(delegate)支持。错误、连接、接收、完整的读取、完整的写入、进度以及断开连接,都可以通过委托模式调用基于run loop的,而不是线程的。虽然可以在主线程或者工作线程中使用它,但你不需要这样做。它异步的调用委托方法,使用NSRunLoop。委托方法包括socket的参数,可让你在多个实例中区分自包含在一个类中。你无需操作流或者socket,这个类帮你做了全部支持基于IPV4和IPV6的TCP流

AsyncUdpSocket是UDP/IP socket网络库,包装自CFSocket。它的工作很像TCP版本,只不过是用于处理UDP的。它包括基于非阻塞队列的发送接收操作,完整的委托支持,基于runloop,自包含的类,以及支持IPV4和IPV6。

以下内容是根据官方网站参考:https://github.com/robbiehanson/CocoaAsyncSocket/wiki

准备工作:如何在iOS项目中使用

基本上是两步:

  1. 将CocoaAsyncSocket项目中的.h和.m文件拖拽到自己项目的Classes目录中
  2. 添加framework:CFNetwork.framework    Security.framework

编写简单的TCP连接

编写个简单的TCP连接应用。HTTP其实就是建立在TCP协议上的。这里就用向网站发起请求和获得响应来演示。

为了形象说明,先手工模拟一下HTTP。这需要用到telnet工具,这是个命令行工具,如果在命令行里敲:

C:\Users\Marshal Wu>telnet
‘telnet’ 不是内部或外部命令,也不是可运行的程序或批处理文件。

说明你使用的是windows vista或者windows7,因为windows xp是默认安装该软件的。

我用的是Mac OSX,上面自带这个工具。如果你出现上面的问题,可参照vista下使用telnet的做法安装telnet。

然后,可以使用这个工具发出socket信息,并接收socket返回信息。下面说一下步骤,如图:

下面用CocoaAsyncSocket来实现。

首先是要实现相关的delegate:

 

  1. #import <UIKit/UIKit.h>  
  2.    
  3. #import "AsyncSocket.h"  
  4.    
  5. @interface SocketDemosViewController : UIViewController<AsyncSocketDelegate>  
  1. <span style="font-family: SimSun;font-size:14px; line-height: 24px; background-color: rgb(249, 249, 249);">然后,在实现代码中:</span>  
  1. - (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port{  
  2.  NSLog(@"did connect to host");  
  3. }  
  4.    
  5. - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{  
  6.  NSLog(@"did read data");  
  7.  NSString* message = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];  
  8.  NSLog(@"message is: \n%@",message);  
  9. }  

 

AsyncSocketDelegate中的方法都是可选的。我实现了对建立连接后以及读取数据的监听。

这些监听需要创建和使用AsyncSocket实例时才能被用到。下面就是这部分代码:

  1. - (void)viewDidLoad {  
  2.     [super viewDidLoad];  
  3.       
  4.     AsyncSocket *socket=[[AsyncSocket alloc] initWithDelegate:self];  
  5.     [socket connectToHost:@"www.baidu.com" onPort:80 error:nil];  
  6.       
  7.     [socket readDataWithTimeout:3 tag:1];  
  8.     [socket writeData:[@"GET / HTTP/1.1\n\n" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:3 tag:1];  
  9. }  

我把这部分代码直接写到controller的viewDidLoad中了。

执行的日志如下:

  1. 2011-07-19 17:17:46.545 SocketDemos[27120:207] did connect to host  
  2. 2011-07-19 17:17:46.620 SocketDemos[27120:207] did read data  
  3. 2011-07-19 17:17:46.621 SocketDemos[27120:207] message is:  
  4. HTTP/1.1 200 OK  
  5. Date: Tue, 19 Jul 2011 09:17:46 GMT  
  6. Server: BWS/1.0  
  7. Content-Length: 7691  
  8. Content-Type: text/html;charset=gb2312  
  9. Cache-Control: private  
  10. Expires: Tue, 19 Jul 2011 09:17:46 GMT  
  11. Set-Cookie: BAIDUID=9389BA38262D7997D220A564154CCA87:FG=1; expires=Tue, 19-Jul-41 09:17:46 GMT; path=/; domain=.baidu.com  
  12. P3P: CP=" OTI DSP COR IVA OUR IND COM "  
  13. Connection: Keep-Alive  

这里的HTTP响应被截断了,因为我们不是要编写真的接收HTTP响应的功能,因此这个缺陷可以忽略。

本来HTTP请求应该是由服务器端来关闭,比如使用telent访问看到的是这样的结尾:


因此,HTTP响应没有完全接收下来,服务器端未断掉连接。可以在客户端关闭连接,这样:

 

  1. [socket readDataWithTimeout:3 tag:1];  
  2. [socket writeData:[@"GET / HTTP/1.1\n\n" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:3 tag:1];  
  3. [socket disconnect];  

另外,可以实现delegate中的这个方法:

 

  1. - (void)onSocketDidDisconnect:(AsyncSocket *)sock{  
  2.  NSLog(@"socket did disconnect");  
  3. }  

这样就可以在日志中监控到关闭连接的信息。

TCP连接读取指定长度的数据

socket连接,经常碰到这样的需求,读取固定长度的字节。这可以通过下面的示例实现。

还是基于HTTP连接做演示。比如取2次,每次50字节。然后停止socket。

可以这样写:

  1. - (void)onSocketDidDisconnect:(AsyncSocket *)sock{  
  2.  NSLog(@"socket did disconnect");  
  3. }  
  4. - (void)viewDidLoad {  
  5.  [super viewDidLoad];  
  6.    
  7.  socket=[[AsyncSocket alloc] initWithDelegate:self];  
  8.  [socket connectToHost:@"www.baidu.com" onPort:80 error:nil];  
  9.    
  10.  data=[[NSMutableData dataWithLength:50] retain];  
  11.    
  12.  [socket readDataToLength:50 withTimeout:5 tag:1];  
  13.  [socket readDataToLength:50 withTimeout:5 tag:2];  
  14.  [socket writeData:[@"GET / HTTP/1.1\n\n" dataUsingEncoding:NSUTF8StringEncoding] withTimeout:3 tag:1];  

在delegate中,主要是这个方法起作用:

  1. - (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)_data withTag:(long)tag{  
  2.  NSLog(@"did read data");  
  3.  NSString* message = [[[NSString alloc] initWithData:_data encoding:NSUTF8StringEncoding] autorelease];  
  4.  NSLog(@"message is: \n%@",message);  
  5.    
  6.  if (tag==2) {  
  7.  [socket disconnect];  
  8.  }  
  9. }  

日志类似这样:

标红色的是两次取出的字节内容。

2.服务器端

参考了demo 自己整理的

部分关键代码

#import "UIDevice-Reachability.h"
#define WELCOME_MSG  0
#define ECHO_MSG     1
#define WARNING_MSG  2
#define READ_TIMEOUT 15.0
#define READ_TIMEOUT_EXTENSION 10.0

- (IBAction)start:(id)sender {
    if(!isRunning)
    {
        int port = [self.airport.text intValue];//监听端口
        
        if(port < 0 || port > 65535)
        {
            port = 0;
        }
        
        NSError *error = nil;
        if(![listenSocket acceptOnPort:port error:&error])
        {
            //[self logError:FORMAT(@"Error starting server: %@", error)];
            NSLog(@"%@",[error localizedDescription]);
            return;
        }
        
        //[self logInfo:FORMAT(@"Echo server started on port %hu", [listenSocket localPort])];
        NSLog(@"%@",[listenSocket localAddress]);
        NSLog(@"%@",[listenSocket localHost]);
        NSLog(@"%u",[listenSocket localPort]);
        isRunning = YES;
        
        [self.airport setEnabled:NO];
        [self.start setTitle:@"stop" forState:(UIControlStateNormal)];
    }
    else
    {
        // Stop accepting connections
        [listenSocket disconnect];
        
        // Stop any client connections
        NSUInteger i;
        for(i = 0; i < [connectedSockets count]; i++)
        {
            // Call disconnect on the socket,
            // which will invoke the onSocketDidDisconnect: method,
            // which will remove the socket from the list.
            [[connectedSockets objectAtIndex:i] disconnect];
        }
        
        //[self logInfo:@"Stopped Echo server"];
        isRunning = false;
        
        [self.airport setEnabled:YES];
        [self.start setTitle:@"start" forState:(UIControlStateNormal)];
    }

}
#pragma asysocketdelegate
- (void)onSocket:(AsyncSocket *)sock didAcceptNewSocket:(AsyncSocket *)newSocket
{
    [connectedSockets addObject:newSocket];
}

- (void)onSocket:(AsyncSocket *)sock didConnectToHost:(NSString *)host port:(UInt16)port
{
    //[self logInfo:FORMAT(@"Accepted client %@:%hu", host, port)];
    NSLog(@"host:%@,port%u",host,port);
    NSString *welcomeMsg = @"Server:Welcome to the AsyncSocket Echo Server\r\n";
    NSData *welcomeData = [welcomeMsg dataUsingEncoding:NSUTF8StringEncoding];
    
    [sock writeData:welcomeData withTimeout:-1 tag:WELCOME_MSG];
    
    [sock readDataToData:[AsyncSocket CRLFData] withTimeout:READ_TIMEOUT tag:0];
}

- (void)onSocket:(AsyncSocket *)sock didWriteDataWithTag:(long)tag
{
    if(tag == ECHO_MSG)
    {
        [sock readDataToData:[AsyncSocket CRLFData] withTimeout:READ_TIMEOUT tag:0];
    }
}

- (void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
{
    NSData *strData = [data subdataWithRange:NSMakeRange(0, [data length] - 2)];
    NSString *msg = [[NSString alloc] initWithData:strData encoding:NSUTF8StringEncoding];
    if(msg)
    { 
        NSLog(@"the messeaege from clinet%@",msg);
        
    }
    else
    {
        NSLog(@"Error converting received data into UTF-8 String");
    }
    
    // Even if we were unable to write the incoming data to the log,
    // we're still going to echo it back to the client.
    [sock writeData:data withTimeout:-1 tag:ECHO_MSG];
}

/**
 * This method is called if a read has timed out.
 * It allows us to optionally extend the timeout.
 * We use this method to issue a warning to the user prior to disconnecting them.
 **/
- (NSTimeInterval)onSocket:(AsyncSocket *)sock
  shouldTimeoutReadWithTag:(long)tag
                   elapsed:(NSTimeInterval)elapsed
                 bytesDone:(NSUInteger)length
{
    if(elapsed <= READ_TIMEOUT)
    {
        NSString *warningMsg = @"Are you still there?\r\n";
        NSData *warningData = [warningMsg dataUsingEncoding:NSUTF8StringEncoding];
        
        [sock writeData:warningData withTimeout:-1 tag:WARNING_MSG];
        
        return READ_TIMEOUT_EXTENSION;
    }
    
    return 0.0;
}

- (void)onSocket:(AsyncSocket *)sock willDisconnectWithError:(NSError *)err
{
    //[self logInfo:FORMAT(@"Client Disconnected: %@:%hu", [sock connectedHost], [sock connectedPort])];
    NSLog(@"%@",[err localizedDescription]);
}

- (void)onSocketDidDisconnect:(AsyncSocket *)sock
{
    [connectedSockets removeObject:sock];
}
-(NSRunLoop *)onSocket:(AsyncSocket *)sock wantsRunLoopForNewSocket:(AsyncSocket *)newSocket{  
  NSLog(@"wants runloop for new socket.");  
   return [NSRunLoop currentRunLoop];  
}  
- (BOOL)onSocketWillConnect:(AsyncSocket *)sock{  
    NSLog(@"will connect");  
    return YES;  
}  

 

  • onSocket:didAcceptNewSocket: AsyncSocket创建了新的Socket用于处理和客户端的请求,如果这个新socket实例你不打算保留(retain),那么将拒绝和该客户端连接
  • onSocket:wantsRunLoopForNewSocket:,提供线程的runloop实例给AsyncSocket,后者将使用这个runloop执行socket通讯的操作
  • onSocketWillConnect:,将要建立连接,这时可以做一些准备工作,如果需要的话
  • onSocket:didConnectToHost:port:,这个方法是建立连接后执行的,一般会在这里调用写入或者读取socket的操作

 

 

下面是跟终端(客户端)通信过程

设置一个端口开始监听

输出窗口输出一下信息

2013-04-01 14:32:44.201 testService[1951:f803] Current host: localhost
2013-04-01 14:32:44.202 testService[1951:f803] Local: 192.168.0.3
2013-04-01 14:32:44.203 testService[1951:f803] All: (
    "192.168.0.3",
    "10.0.2.1",
    "169.254.201.77"
)
2013-04-01 14:32:52.466 testService[1951:f803] <1002225e 00000000 00000000 00000000>
2013-04-01 14:32:52.466 testService[1951:f803] 0.0.0.0
2013-04-01 14:32:52.466 testService[1951:f803] 8798

打开终端输入以下信息

输出窗口输出的日志

2013-04-01 14:34:21.405 testService[1951:f803] wants runloop for new socket.
2013-04-01 14:34:21.405 testService[1951:f803] will connect
2013-04-01 14:34:21.406 testService[1951:f803] host:192.168.0.3,port55706
2013-04-01 14:34:23.825 testService[1951:f803] the messeaege from clinethello
2013-04-01 14:34:25.992 testService[1951:f803] the messeaege from clinetjinjiantong
2013-04-01 14:34:38.464 testService[1951:f803] the messeaege from clinetmy name is jinjiantong
2013-04-01 14:35:01.064 testService[1951:f803] the messeaege from clinetis time out?
2013-04-01 14:35:26.149 testService[1951:f803] Read operation timed out

这样完成简单的完成了客户端和服务器端的通信过程

通信过程很简单,服务器端扳回客户端输入的内容

 

 

编写简单的UDP应用

如何加入项目

      1、下载地址:https://github.com/robbiehanson/CocoaAsyncSocket

      2、下载之后导入AsyncUdpSocket.h和AsyncUdpSocket.m文件进入你的项目,本人使用xcode4.2,不加类库可以使用,如果需要请另行加入CFNetwork.framework框架。

      3、如果你的项目使用ARC的话,应该已经可以正常编译了,如果你的项目不是使用的ARC,在AyncUdpSocket.m文件中有说明,

         加入编译条件:在项目target -> build phases -> compile sources -> AsyncUdpSocket文件后面加入 -fobjc-arc ,这是为了使编译器编译的时候将此文件在arc的条件下编译。

  参考:http://blog.csdn.net/bjx327660180/article/details/8105289

首先,编写发送UDP数据报的示例。这需要有个服务器端能接收到内容。用Node.Js写了个简单的接收端:

 

[javascript] view plaincopy
  1. var dgram = require("dgram");  
  2. var server = dgram.createSocket("udp4");  
  3.   
  4. server.on("message"function (msg, rinfo) {  
  5.     console.log('server got data:{ message : ' + msg + ' }【' + rinfo.address + ":" + rinfo.port+ "】");  
  6.     var message=new Buffer("333333");  
  7.     server.send(message, 0, message.length, rinfo.port, rinfo.address, function(err, bytes){  
  8.         if(err){  
  9.             console.log('error : '+err);  
  10.         }  
  11.     });  
  12. });  
  13.   
  14. server.on("listening"function () {  
  15.     var address = server.address();  
  16.     console.log("server listening " +  
  17.         address.address + ":" + address.port);  
  18. });  
  19.   
  20. server.bind(8080);  

下面写发送的代码:

 

在.h文件里定义socket

 

  1. #import "AsyncUdpSocket.h"  
  2. @interface ViewController : UIViewController{  
  3.     AsyncUdpSocket *socket;     
  4. }  

在.m文件里使用socket(在.m文件里定义socket时deleget将不起作用,所以:一定要把socket定义在.h文件里

 

  1. socket=[[AsyncUdpSocket alloc]initWithDelegate:self];  
  2.    
  3. NSData *data=[@"Hello from iPhone" dataUsingEncoding:NSUTF8StringEncoding];  
  4. [socket sendData:data toHost:@"192.168.0.165" port:8080 withTimeout:-1 tag:1];  
  5. NSLog(@"send upd complete.");  

下面,写个接收端的代码:

 

  1. AsyncUdpSocket *socket=[[AsyncUdpSocket alloc] initWithDelegate:self];  
  2.   
  3. NSError *error = nil;  
  4. [socket bindToPort:5555 error:&error];  
  5.   
  6. if (error) {  
  7. NSLog(@"error: %@",error);  
  8. }  
  9.   
  10. [socket receiveWithTimeout:-1 tag:1];  
  11. NSLog(@"start udp server");  

另外,至少写这个delegate方法:

  1. - (BOOL)onUdpSocket:(AsyncUdpSocket *)sock  
  2.      didReceiveData:(NSData *)data  
  3.             withTag:(long)tag  
  4.            fromHost:(NSString *)host  
  5.                port:(UInt16)port{  
  6.     NSLog(@"received data: %@",[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);  
  7.     return YES;  
  8. }  

发送端,还是用Node.Js写个测试代码:

 

[javascript] view plaincopy
  1. var dgram = require('dgram');  
  2. var client = dgram.createSocket("udp4");  
  3.   
  4. var message = new Buffer('I\n');  
  5. client.send(message, 0, message.length, 8080, "localhost"function(err, bytes){  
  6.     if(err){  
  7.         console.log('error : '+err);  
  8.     }else{  
  9.         console.log('bytes : '+bytes);  
  10.     }  
  11.     client.close();  
  12. });  
  13. client.bind(8080);  

在iPhone日志中:

1
2
2011-07-20 15:23:33.571 SocketDemos[795:707] start udp server     
2011-07-20 15:23:47.395 SocketDemos[795:707] received data: Hello

收到了数据报。

使用UDP发送和接收组播

这里主要关注的是接收,一方面是需求上要求,另一方面,碰到过Android Wifi获取组播问题,担心iOS也有类似的机制。后来测试发现没有那么麻烦(打开组播锁)。

为了测试,还是用java编写了个发送UDP广播的简单代码:

 

[java] view plaincopy
  1. public static void main(String[] args) throws IOException {  
  2.  int port=3333;  
  3.  MulticastSocket socket=new MulticastSocket(port);  
  4.  InetAddress address=InetAddress.getByName("239.0.0.1");  
  5.  socket.joinGroup(address);  
  6.  byte[] data="Hello everyone.".getBytes();  
  7.  DatagramPacket datagramPacket=new DatagramPacket(data,data.length,address,port);  
  8.  socket.send(datagramPacket);  
  9.  System.out.println("send ok.");}  

编写的iOS代码:

在.h文件里定义socket

 

  1. #import "AsyncUdpSocket.h"  
  2. @interface ViewController : UIViewController{  
  3.     AsyncUdpSocket *socket;     
  4. }  

在.m文件里使用socket(在.m文件里定义socket时deleget将不起作用,所以:一定要把socket定义在.h文件里

  1. socket=[[AsyncUdpSocket alloc] initWithDelegate:self];  
  2.   
  3. NSError *error = nil;  
  4. [socket bindToPort:3333 error:&error];  
  5. [socket enableBroadcast:YES error:&error];  
  6. [socket joinMulticastGroup:@"239.0.0.1" error:&error];  
  7.   
  8. if (error) {  
  9.     NSLog(@"error: %@",error);  
  10. }  
  11.   
  12. [socket receiveWithTimeout:-1 tag:1];  
  13. NSLog(@"start udp server");  

delegate和上面接收普通UDP一模一样:

  1. - (BOOL)onUdpSocket:(AsyncUdpSocket *)sock  
  2.      didReceiveData:(NSData *)data  
  3.             withTag:(long)tag  
  4.            fromHost:(NSString *)host  
  5.                port:(UInt16)port{  
  6.     NSLog(@"received data: %@",[[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);  
  7.     return YES;  
  8. }  

测试得到的日志:

 

    1. 2011-07-20 16:14:30.338 SocketDemos[860:707] start udp server       
    2. 2011-07-20 16:14:42.829 SocketDemos[860:707] received data: Hello everyone.  

 

分享到:
评论

相关推荐

    基于NSGA2与熵权TOPSIS的电力系统储能选址定容优化及Matpower潮流计算研究

    内容概要:本文详细探讨了利用NSGA2算法进行电力系统中储能系统的选址和定容优化,并结合熵权TOPSIS方法选择最优解。首先介绍了使用Matpower工具包进行潮流计算的基础步骤,随后深入讨论了储能系统引入后的复杂性和优化目标设定。文中展示了如何构建目标函数,包括储能的投资成本和系统电压偏差,并详细解释了NSGA2算法的具体实现,如种群初始化、交叉变异操作以及约束条件处理。最后,通过熵权法确定权重并应用TOPSIS方法对多个优化结果进行评估,选出综合性能最佳的储能配置方案。 适合人群:从事电力系统规划、优化算法研究的专业人士,尤其是对储能系统优化感兴趣的科研人员和技术开发者。 使用场景及目标:适用于需要解决电力系统中储能系统选址和定容问题的实际工程项目。主要目标是在满足系统稳定性要求的前提下,最小化储能系统的投资成本,提高系统的经济性和可靠性。 其他说明:文章提供了详细的代码片段和理论推导,帮助读者更好地理解和实施所提出的优化方法。此外,还提到了一些实际应用中的注意事项,如SOC约束处理、参数选择等,为后续的研究和应用提供了宝贵的实践经验。

    基于python+pyqt5实现视频自动化下载、剪辑和上传系统源码+项目说明.zip

    基于python+pyqt5实现视频自动化下载、剪辑和上传系统源码+项目说明.zip 该项目是用脚本实现部分视频网站视频内容的自动化下载、剪辑以及上传,其中界面是用PyQT做的。 使用的浏览器驱动是undetected_chromedriver,可以跳过tiktok的机器人检查 使用的浏览器是91,版本:Google_Chrome_(64bit)_v91.0.4472.77 【功能】 自动从各种视频网站下载视频 支持视频剪辑和合集制作 支持自动上传视频到视频网站 技术栈 Python PyQT undetected_chromedriver

    西门子S7-1200双套三坐标6轴联动控制系统的设计与实现

    内容概要:本文详细介绍了西门子S7-1200双套三坐标6轴联动控制系统的开发与调试经验。主要内容涵盖双PLC通信机制、轴控制逻辑、安全联锁设计以及触摸屏程序绑定等方面。文中通过具体代码示例展示了如何利用SCL语言实现高效稳定的多轴联动控制,并分享了实际项目中的最佳实践和技术难点解决方案。此外,还讨论了程序结构优化、报警代码设计、数据块管理等关键环节,强调了模块化设计思想的应用及其带来的效率提升。 适合人群:从事工业自动化领域的工程师,尤其是熟悉西门子PLC编程的专业人士。 使用场景及目标:适用于需要进行复杂运动控制的自动化生产线,如汽车制造、电子装配等行业。主要目标是提高生产效率,确保设备运行的安全性和稳定性。 其他说明:文中提到的许多技术和方法不仅限于特定型号的PLC,对于其他品牌的控制器也有一定的借鉴意义。同时,提供的代码片段可以直接应用于类似项目中,帮助开发者快速搭建可靠的控制系统。

    NFC Tools Pro

    NFC Tools是一个应用程序,允许你在你的 NFC 标签和其他 RFID 兼容芯片上读取或写入或编程代码任务。NFC Tools PRO版本包括很多其他的附加功能,比如配置文件管理等。保存你的NFC标签或任务的配置文件,以便你以后重新使用它们。导出和导入很容易。NFC Tools PRO官方版允许你直接从现有的 NFC 标签导入你的记录或任务。 你可以很快编辑你的标签。此外还可以直接运行你的任务配置文件,不需要NFC 标签。

    protobuf-6.30.1-py3-none-any.whl

    该资源为protobuf-6.30.1-py3-none-any.whl,欢迎下载使用哦!

    FLAC3D中壳单元与衬砌单元内力提取及处理技巧

    内容概要:本文详细介绍了如何在FLAC3D中提取壳单元和衬砌单元的关键内力数据,如弯矩、轴力和剪力。针对壳单元,文中提供了具体的FISH命令和函数,展示了如何利用gp.extra属性提取弯矩,并强调了局部坐标系方向的重要性。对于衬砌单元,则介绍了专门的命令和注意事项,如使用liner组件提取轴力和剪力,以及如何处理弯矩数据。此外,还分享了一些实用的经验和技巧,如批量数据处理、单位换算、内力符号规则等。最后,提到了使用Python进行后处理的方法,将提取的数据转化为更直观的形式,便于进一步分析。 适合人群:从事岩土工程、隧道工程及相关领域的工程师和技术人员,尤其是对FLAC3D有一定基础的用户。 使用场景及目标:帮助用户掌握FLAC3D中壳单元和衬砌单元内力提取的具体方法,提高工作效率,确保数据分析的准确性。适用于需要进行结构内力分析、支护设计优化等项目的工程师。 其他说明:文章不仅提供了详细的命令和函数示例,还分享了许多实战经验和常见错误的规避方法,有助于初学者少走弯路。同时,强调了内力符号规则和单位换算的重要性,避免因疏忽导致的重大失误。

    ST PMSM FOC电机控制资料包2.0:全面解析STM32电机控制核心技术与实战技巧

    内容概要:本文详细介绍了ST公司发布的HL07:ST PMSM FOC电机控制资料包2.0的内容及其应用。资料包涵盖了ST芯片电机控制的全源代码、详细文档、多个工程源码、stm32库培训资料及例程源码。文中通过具体的代码示例,如GPIO初始化、PWM配置、ADC采样、Clarke变换、PID调节器、SVPWM生成等,深入剖析了电机控制的关键技术和优化技巧。此外,还揭示了一些隐藏的技术细节和调试技巧,如硬件同步、动态调整PID参数、电机参数自识别等。 适合人群:电机控制工程师、嵌入式开发人员、尤其是对STM32和FOC算法感兴趣的开发者。 使用场景及目标:帮助读者深入了解ST芯片电机控制的具体实现,掌握从硬件配置到算法优化的全过程,提高实际项目的开发效率和质量。适用于需要进行电机控制系统设计、调试和优化的工程项目。 其他说明:资料包中的代码和文档非常实用,提供了丰富的实战经验和优化建议,尤其适合初学者和有一定基础的研发人员。同时,文中提到的一些特殊技巧和注意事项有助于避免常见的开发陷阱,提升系统的稳定性和性能。

    人工智能2025年AI领袖与技术发展趋势:多模态AI、量子计算及行业应用展望

    内容概要:文章探讨了2025年AI技术发展趋势及潜在的GPT级技术突破。首先回顾了GPT系列模型的发展历程及其对自然语言处理领域的深远影响。接着,通过介绍Geoffrey Hinton、李飞飞和张晨等AI领袖的观点,阐述了AI技术在实际应用场景中的挑战与机遇。文中详细描述了AI大模型的演进,包括多模态技术的发展、轻量化趋势以及可控性和可解释性的提升。此外,还介绍了AI计算力的革命性升级,如量子计算、云计算+AI和边缘AI的发展。最后,文章分析了AI在医疗、金融、教育、自动驾驶等行业的落地应用,并指出了面临的挑战与机遇,展望了未来的技术和社会影响。 适合人群:对AI技术感兴趣的从业者、研究人员、企业家及政策制定者。 使用场景及目标:①了解AI技术的最新进展和未来趋势;②探索AI技术在各行业的应用前景;③评估AI技术带来的挑战与机遇,为相关决策提供参考。 阅读建议:本文内容涵盖广泛,既有技术细节又有宏观展望,建议读者结合自身背景选择感兴趣的部分深入阅读,重点关注与自身行业或研究方向相关的章节。

    基于樽海鞘算法优化的极限学习机回归预测及其与BP、GRNN、ELM的性能对比研究

    内容概要:本文详细探讨了基于樽海鞘算法(SSA)优化的极限学习机(ELM)在回归预测任务中的应用,并与传统的BP神经网络、广义回归神经网络(GRNN)以及未优化的ELM进行了性能对比。首先介绍了ELM的基本原理,即通过随机生成输入层与隐藏层之间的连接权重及阈值,仅需计算输出权重即可快速完成训练。接着阐述了SSA的工作机制,利用樽海鞘群体觅食行为优化ELM的输入权重和隐藏层阈值,从而提高模型性能。随后分别给出了BP、GRNN、ELM和SSA-ELM的具体实现代码,并通过波士顿房价数据集和其他工业数据集验证了各模型的表现。结果显示,SSA-ELM在预测精度方面显著优于其他三种方法,尽管其训练时间较长,但在实际应用中仍具有明显优势。 适合人群:对机器学习尤其是回归预测感兴趣的科研人员和技术开发者,特别是那些希望深入了解ELM及其优化方法的人。 使用场景及目标:适用于需要高效、高精度回归预测的应用场景,如金融建模、工业数据分析等。主要目标是提供一种更为有效的回归预测解决方案,尤其是在处理大规模数据集时能够保持较高的预测精度。 其他说明:文中提供了详细的代码示例和性能对比图表,帮助读者更好地理解和复现实验结果。同时提醒使用者注意SSA参数的选择对模型性能的影响,建议进行参数敏感性分析以获得最佳效果。

    工业自动化中汇川PLC与基恩士PLC基于EIP通讯的联机实现及应用

    内容概要:本文详细介绍了汇川PLC与基恩士PLC通过Ethernet/IP (EIP) 协议实现联机的方法及其应用场景。首先,文章解释了硬件配置,包括基恩士KV-7300 CPU搭配KV-EP21v以太网通信模块以及汇川AM-400系列PLC的网口连接。接下来,分别阐述了基恩士和汇川PLC的程序框架,涵盖初始化EIP通讯模块、设置IP地址、建立连接、数据映射及心跳检测机制等关键技术点。此外,文中提供了具体的代码示例和调试建议,如使用Wireshark抓包工具排查问题,并强调了数据同步、字节序转换、超时处理等方面需要注意的地方。最后,分享了一些实践经验,例如确保正确的IP地址分配、合理的缓冲区大小规划、良好的接地措施等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对PLC编程有一定基础并希望深入了解不同品牌PLC间通讯机制的专业人士。 使用场景及目标:适用于需要将不同品牌PLC集成到同一个控制系统中的工业项目,旨在提高系统的灵活性和互操作性。通过掌握本文介绍的技术要点,可以有效减少因PLC品牌差异带来的兼容性和稳定性问题。 其他说明:文中不仅提供了理论指导,还结合实际案例进行了深入浅出的讲解,帮助读者更好地理解和应用相关技术。同时,针对可能出现的问题给出了预防和解决方案,使读者能够在实践中少走弯路。

    基于STM32F4的VESC非线性磁链观测器移植与优化

    内容概要:本文详细记录了作者将VESC项目的非线性磁链观测器移植到STM32F4开发板的过程。首先介绍了FOC技术和VESC源码的重要性和特点,然后重点阐述了非线性磁链观测器的实现方法及其核心代码。接着讨论了移植过程中遇到的技术难题,如实时性、稳定性、中断处理、电流采样等问题,并分享了解决这些问题的具体措施。最后展示了测试结果,证明了移植的成功以及观测器的良好性能。 适合人群:具有一定嵌入式开发经验的研发人员,特别是从事电机控制领域的工程师和技术爱好者。 使用场景及目标:适用于希望深入理解VESC源码和非线性磁链观测器的工作机制,掌握STM32F4平台上FOC算法实现的人群。目标是在实际项目中应用这些技术,提高电机控制系统的性能。 其他说明:文中提供了大量实用的代码片段和调试技巧,帮助读者更好地理解和解决问题。此外,作者还分享了一些个人经验和心得,增加了文章的趣味性和实用性。

    Quectel-LTE&5G-Windows-USB-Driver-V2.2.6-beta-20201230

    移远EC20 Windows驱动 操作系统 - 桌面系统 - 移远EC20 Windows驱动

    检证资料jianzhen.ppt

    检证资料jianzhen.ppt

    ### 【嵌入式开发】基于Qt的ATK-DLRK3568实战指南:从入门到项目实战题:嵌

    内容概要:本文档《ATK-DLRK3568嵌入式Qt开发实战V1.2》是正点原子出品的一份面向初学者的嵌入式Qt开发指南,主要内容涵盖嵌入式Linux环境下Qt的安装配置、C++基础、Qt基础、多线程编程、网络编程、多媒体开发、数据库操作以及项目实战案例。文档从最简单的“Hello World”程序开始,逐步引导读者熟悉Qt开发环境的搭建、常用控件的使用、信号与槽机制、UI设计、数据处理等关键技术点。此外,文档还提供了详细的项目实战案例,如车牌识别系统的开发,帮助读者将理论知识应用于实际项目中。 适合人群:具备一定Linux和C++基础,希望快速入门嵌入式Qt开发的初学者或有一定开发经验的研发人员。 使用场景及目标: 1. **环境搭建**:学习如何在Ubuntu环境下搭建Qt开发环境,包括安装必要的工具和库。 2. **基础知识**:掌握C++面向对象编程、Qt基础控件的使用、信号与槽机制等核心概念。 3. **高级功能**:理解多线程编程、网络通信、多媒体处理、数据库操作等高级功能的实现方法。 4. **项目实战**:通过具体的项目案例(如车牌识别系统),巩固

    tcl-tclxml-devel-3.2-26.el8.x64-86.rpm.tar.gz

    1、文件说明: Centos8操作系统tcl-tclxml-devel-3.2-26.el8.rpm以及相关依赖,全打包为一个tar.gz压缩包 2、安装指令: #Step1、解压 tar -zxvf tcl-tclxml-devel-3.2-26.el8.tar.gz #Step2、进入解压后的目录,执行安装 sudo rpm -ivh *.rpm

    C盘清理bat脚本自动清理C盘垃圾文件

    C盘清理bat脚本自动清理C盘垃圾文件

    桶排.txt

    桶排

    基于混沌系统的图像加密算法:循环移位扰乱与水平垂直扩散的应用及性能评估

    内容概要:本文详细介绍了利用混沌系统进行图像加密的方法,重点探讨了Logistic映射生成混沌序列用于图像加密的具体实现。首先,通过生成混沌序列并对其进行预热处理,确保序列的随机性和稳定性。然后,采用循环移位扰乱方法对图像像素进行重新排列,使图像像素位置发生改变。接着,通过水平和垂直扩散步骤进一步打乱像素之间的关联性,增强了加密效果。文中还展示了如何通过直方图、信息熵和相关系数等指标评估加密效果,验证了该方法的有效性。 适合人群:对图像加密技术和混沌系统感兴趣的科研人员、信息安全领域的开发者和技术爱好者。 使用场景及目标:适用于研究和开发高效的图像加密算法,特别是在需要高安全性的应用场景中,如军事通信、隐私保护等领域。目标是提供一种基于混沌系统的高效、安全的图像加密解决方案。 其他说明:文中提供了详细的Python代码实现,帮助读者更好地理解和实践该加密方法。同时,强调了在实际应用中需要注意的一些关键点,如参数选择和优化,以确保最佳的加密效果。

    基于EEMD奇异值熵的滚动轴承故障诊断方法研究

    基于EEMD奇异值熵的滚动轴承故障诊断方法研究

    【数据结构与算法】分块查找算法实现:有序分块数据快速检索方法研究

    内容概要:本文档介绍了分块查找的基本思想及其具体实现方法。分块查找的核心在于将一个数据集划分为若干个块,块内部元素可以无序排列,但块间元素必须保持有序(对于非递减序列,后一块的所有元素均大于前一块)。文档通过C#语言实现了分块查找算法,定义了IndexBlock结构体用于存储每个块的最大值、起始位置和结束位置,并展示了如何初始化分块以及执行具体的查找操作。最后通过一个简单的例子演示了分块查找的应用,当查找成功时返回元素在数组中的索引,否则返回-1表示查找失败。; 适合人群:计算机科学专业学生或有一定编程基础的技术人员。; 使用场景及目标:①理解分块查找算法的工作原理;②掌握利用C#实现分块查找的具体步骤;③学习如何根据实际需求选择合适的查找算法以提高效率。; 其他说明:此文档不仅提供了理论性的概念解释,还结合了实际代码示例帮助读者更好地理解分块查找算法,建议读者在阅读过程中尝试运行代码并理解每一部分的功能。

Global site tag (gtag.js) - Google Analytics