川崎机器人TCP通信做服务端与多个客户端进行通信

前言

最近在玩川崎机器人,在玩的过程中,机器人通信程序使用的是官方给的一个案例程序,案例程序中机器人为服务器时,只能服务一个客户端,这样子的服务器就算不上服务器。

于是,为了能让机器人服务多个客户端,博主决定在案例程序的基础上进行优化,实现一个真正的服务器,同时,记录一下自己的学习过程。


正文

1.首先了解一下川崎机器人做服务器时会用到的TCP通信命令

  • TCP_LISTEN 将一个自己给定的端口号用来创建服务器
  • TCP_ACCEPT 检查自己给定的端口号是否接收到连接请求
  • TCP_SEND 发送数据给客户端
  • TCP_RECV 接收客户端的数据

用好上面4个TCP通信命令就可以跟客户端正常通信了

2.然后了解一下这4个命令的参数

TCP_LISTEN 返回值,端口号
例如:TCP_LISTEN res,8888

要注意一点的就是端口号的范围:8192~65535

TCP_ACCEPT 返回值,端口号,超时时间,客户端IP地址数组
例如:TCP_ACCEPT clientid,8888,60,ip[1]

返回值如果大于0,表示有个客户端跟服务器连接成功,并且这个返回值就是服务器用来识别这个客户端的,收发数据命令的套接字号就可以用这个返回值,端口号跟TCP_LISTEN参数中的端口号一致,参数超时时间客户端IP地址数组可以省略

TCP_SEND 返回值,套接字号,字符串数组,元素数,超时时间
例如:TCP_SEND result,clientid,$send[1],1,60

套接字号是TCP_ACCEPT返回值,参数超时时间单位是秒,默认值为1,可以省略

TCP_RECV 返回值,套接字号,接收数据字符串数组,元素数,超时时间,最大字节数
例如:TCP_RECV res,clientid,$recv[1],1,1,255

参数超时时间最大字节数可以省略,最大字节数范围:1~255,默认值为255

收发数据都是大端模式

3.代码实现
要实现服务端跟多个客户端同时通信,需要满足两个条件
①服务器要不断检查是否有新的客户端连接
②当有客户端连接成功时要不断检查客户端是否发送了数据

先实现条件①

.PROGRAM autostart.pc () #0; 服务端等待连接
  ; *******************************************************************
  ;
  ; Program:      autostart.PC
  ; Comment:      TCP通信,机器人作服务端
  ; Author:       User
  ;
  ; Date:         2024/3/17
  ;
  ; *******************************************************************
  existclient = FALSE ;存在客户端的标志位,方便后面循环检测是否有客户端发送数据给服务器
  recvmsg = FALSE	  ;复位接收标志位,表示没有收到数据
  portS = 8888        ;设置通讯端口
  max_lengthS = 255   ;设置最长接收字节数
  tout_openS = 60     ;设置端口打开超时时间
  tout_recS = 10      ;设置端口接收超时时间
  sock_idS = 0        ;清空套接字变量
  rrets = 0           ;清空套接字变量
  eretS = 0           ;清空报错信息
  touts = 60          ;设置超时
  clientnums = 0      ;记录客户端的数量
  TCP_LISTEN sock_idS, portS ;创建端口号为8888的服务器
  IF sock_idS < 0 THEN  ;创建(服务器)套接字错误
      PRINT "创建服务器失败"
  ELSE ;创建套接字成功会有一个ip地址为0.0.0.0 端口号为8888的客户端
    PRINT "TCP_LISTEN OK", sock_idS
  END
 
  WHILE TRUE DO ;循环等待新的客户端连接
    TWAIT 0.5
    TCP_ACCEPT sock_idS, portS, tout_openS, ip[1] ;在tout_openS秒内等待新的连接
    IF sock_idS > 0 THEN
      PRINT "与", ip[1], ".", ip[2], ".", ip[3], ".", ip[4], "建立连接"
      sockets[clientnums] = sock_idS	;用一个数组来保存客户端的套接字号
      PRINT "为客户端", clientnums, ":socket id = ", sockets[clientnums]
      clientnums = clientnums + 1
      existclient = TRUE	
      socketstr = sock_idS
      $sendMsg[1] = "Hello "+$ENCODE(/D,socketstr)
      TCP_SEND sretS, sock_idS, $sendMsg[1], buf_nS, touts	;发送Hello sock_idS给刚刚连接上的客户端
    END
    TCP_STATUS Tcp_cl_c, .port[0], .sock[0], .err[0], .sub[0], .$ip_add[0]	;查看服务器的连接状态
    PRINT "当前有", Tcp_cl_c, "个客户端"
    FOR .num = 1 TO Tcp_cl_c
      PRINT "ScoketID:", .sock[.num - 1], "IP:", .$ip_add[.num - 1], "[", .port[.num - 1], "]"
    END
  END
.END

然后是②的实现

.PROGRAM autostart2.pc () #0; 服务端收发数据
  ; *******************************************************************
  ;
  ; Program:      autostart2.pc
  ; Comment:      服务端收发数据
  ; Author:       User
  ;
  ; Date:         2024/3/17
  ;
  ; *******************************************************************
  curclient = 0
  WHILE TRUE DO
    TWAIT 0.05
    IF existclient THEN
      FOR .cli = 0 TO clientnums - 1
        .nums = 0 ;.nums为接收到的数据有多少位
        TCP_RECV rrets, sockets[.cli], $recv_bufS[1], .nums, 1, max_lengthS
        IF .nums > 0 AND rrets <> -34024 THEN
          PRINT "接收", sockets[.cli], "的数据:", $recv_bufS[1]
          curclient = sockets[.cli] ;当前发送数据的客户端
          $cmdtextS = $recv_bufS[1]
          $cmdstringS = $cmdtextS
          $cmdtextS = ""
          $recv_bufS[1] = ""
          recvmsg = TRUE;接收成功打开标志位
        END
      END
      IF $Ser_Send <> "" THEN
        $send_bufS[1] = $Ser_Send
        buf_nS = 1
        .ret = 1
        IF $cmdstringS == "a" THEN	;收到客户端发送a,服务器会给所有客户端发送$Ser_Send
          FOR .cli = 0 TO clientnums - 1
            TCP_SEND sretS, sockets[.cli], $send_bufS[1], buf_nS, touts
            IF sretS < 0 THEN
              .ret = -1
              PRINT "发送给", sockets[.cli], ":", $Ser_Send, "失败"
            ELSE
              PRINT "发送给", sockets[.cli], ":", $Ser_Send, "成功"
              $Ser_Send = ""
            END
          END
        END
        IF curclient > 0 AND $cmdstringS <> "a" THEN
          TCP_SEND sretS, curclient, $send_bufS[1], buf_nS, touts
          IF sretS < 0 THEN
            .ret = -1
            PRINT "发送给", curclient, ":", $Ser_Send, "失败"
          ELSE
            PRINT "发送给", curclient, ":", $Ser_Send, "成功"
            $Ser_Send = ""
          END
        END
      END
    END
  END
.END

最后将autostart.pc () 和autostart2.pc () 程序上传到川崎机器人上,后台运行这两个程序,川崎机器人就可以做服务器同时跟多个客户端通信了

以上内容参考以下文章总结:

川崎机器人E系列 TCP/IP通信功能手册


转载请注明出处:CSDN CA9


  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值