Socket 模块

CBrother提供了一个Socket扩展,它可以作为tcp服务器与客户端使用,也可以作为udp服务器与客户端使用。

TcpModule

TcpModule在windows下使用的是IOCP,在linux下使用的是epoll,在macOS下使用的是poll模型。

·TcpModule接口

函数描述参数用法
setTcpAction(actobj) 设置响应接口 actobj:响应对象 tcpModule.setTcpAction(actobj)
start() 启动服务,返回true表示启动成功 tcpModule.start()
stop() 停止服务 tcpModule.stop()
setThreadCount(cnt) 设置工作线程数量 默认5个 可以大到CPU核数3 但是消耗资源增多 cnt:响应线程数量 tcpModule.setThreadCount(8)
setMaxConnectCount(cnt) 设置最大连接数 cnt:数量,根据需求设置 过大了开销资源很大 默认2048 tcpModule.setMaxConnectCount(5000)
setSockNormalBuflLen (recvLen,sendLen) 设置socket接收缓冲和发送缓冲默认值 recvLen:接收缓冲 sendLen:发送缓冲 默认4096 tcpModule.setSockNormalBuflLen(1024\10,1024*15)
addListenPort(port,listen_ip) 添加监听端口和IP 可以同时监听多个端口 port:监听端口 listen_ip:监听IP 默认0.0.0.0表示IPV4全IP ::表示IPV6全IP 表示IPV6与IPV4兼容的全IP tcpModule.addListenPort(6060)tcpModule.addListenPort(6061,"\")
connect(ip,port) 主动连接某TCP服务器,成功返回socketid,失败返回-1 ip:ip地址,port:端口 tcpModule.connect("127.0.0.1",6060)
sendData(socketid,str) 发送数据,返回true为成功 socketid:socket标示 str:字符串 tcpModule.sendData(socketid,"hello")
sendData(socketid,byteArray,len) 发送数据,返回true为成功 socketid:socket标示 byteArray:ByteArray对象 len:发送长度,不传将发送byteArray所有数据 tcpModule.sendData(socketid,byteArray)tcpModule.sendData(socketid,byteArray,10)
closeSocket(socketid) 关闭socket,返回true为成功 socketid:socket标示 tcpModule.closeSocket(socketid)
getRemoteIP(socketid) 获取socket对端IP socketid:socket标示 var ip = tcpModule.getRemoteIP(socketid)
setSockBuflLen (socketid,recvLen,sendLen) 设置socketid接收缓冲和发送缓冲大小 socketid:socket标示 recvLen:接收缓冲 sendLen:发送缓冲 不设置用默认的 只能在OnAccept和OnConnect里调用 tcpModule.setSockBuflLen(socketid,10*1024,10,1024)
getSocketCount() 获取当前管理的socket数量 var cnt = tcpModule.getSocketCount()
openLog(logname) 打开日至 在工程跟目录建立log目录 默认关闭,建议打开 日志文件名称 tcpModule.openLog("serv")

setSocketAction,setThreadCount,setMaxConnectCount,setSockNormalBuflLen,addListenPort要在start之前调用。

·TcpModule 响应Action类可以有如下接口

function OnAccept(sock),有新的连接。

function OnClose(sock),连接断开。

function OnRecv(sock,byteArray,len)接收到数据。

function OnSend(sock,len)发送成功。

function OnConnect(sock)主动连接对端成功。

这个方法会被多线程调用,如果要访问公共资源需要加锁。但对于同一个socket而言,OnRecv是串行的。

·TcpModule 例子

服务器例子

  1. import CBSocket.code
  2. class TcpAction
  3. {
  4. var tcpModule;
  5. function OnAccept(sock)
  6. {
  7. print "accept " + sock;
  8. }
  9. function OnClose(sock)
  10. {
  11. print "onclose " + sock;
  12. }
  13. function OnRecv(sock,byteArray,len)
  14. {
  15. print "onrecv " + sock + " " + byteArray.readString() + " len:" + len;
  16. var byteArray = new ByteArray();
  17. byteArray.writeString("hello tcp client");
  18. tcpModule.sendData(sock,byteArray);
  19. }
  20. function OnSend(sock,len)
  21. {
  22. print "onsend " + sock + " " + len;
  23. }
  24. }
  25. function main(parm)
  26. {
  27. var tcpModule = new TcpModule();
  28. var tcpAction = new TcpAction();
  29. tcpAction.tcpModule = tcpModule;
  30. tcpModule.setTcpAction(tcpAction); //设置TCP处理类
  31. tcpModule.addListenPort(6060); //监听6060端口
  32. tcpModule.addListenPort(6061,"*"); //监听6061端口,IPV4和IPV6兼容
  33. tcpModule.start();
  34. while(1) //主线程不能退出
  35. {
  36. Sleep(1000);
  37. }
  38. }

客户端例子

  1. import CBSocket.code
  2. class TcpAction
  3. {
  4. var tcpModule;
  5. function OnClose(sock)
  6. {
  7. print "onclose " + sock;
  8. }
  9. function OnRecv(sock,byteArray,len)
  10. {
  11. print "onrecv " + sock + " " + byteArray.readString() + " len:" + len;
  12. }
  13. function OnSend(sock,len)
  14. {
  15. print "onsend " + sock + " " + len;
  16. }
  17. function OnConnect(sock)
  18. {
  19. print "onconnect " + sock;
  20. var byteArray = new ByteArray();
  21. byteArray.writeString("hellp tcp server!");
  22. tcpModule.sendData(sock,byteArray);
  23. }
  24. }
  25. function main(parm)
  26. {
  27. var tcpModule = new TcpModule();
  28. var tcpAction = new TcpAction();
  29. tcpAction.tcpModule = tcpModule;
  30. tcpModule.setTcpAction(tcpAction); //设置TCP处理类
  31. tcpModule.start();
  32. tcpModule.connect("127.0.0.1",6060);
  33. while(1) //主线程不能退出
  34. {
  35. Sleep(1000);
  36. }
  37. }

客户端结果如下:

  1. onconnect 131072
  2. onsend 131072 18
  3. onrecv 131072 hello tcp client len:17

服务端结果如下:

  1. accept 131072
  2. onrecv 131072 hellp tcp server! len:18
  3. onsend 131072 17

UdpModule

·UdpModule接口

函数描述参数返回值用法
setUdpAction(actobj) 设置响应接口 actobj:响应对象 udpModule.setUdpAction(actobj)
start() 启动服务 true:启动成功 udpModule.start()
stop() 停止服务 udpModule.stop()
setRecvBufLen(recvLen) 设置最大接收数据包大小 recvLen:接收缓冲 默认4096 udpModule.setRecvBufLen(1024*10)
listen(port,listen_ip) 添加监听端口和IP 可以同时监听多个端口 port:监听端口 listen_ip:监听IP 默认0.0.0.0表示IPV4全IP ::表示IPV6全IP 表示IPV6与IPV4兼容的全IP udpModule.listen(6060)udpModule.listen(6061,"\")
connectSendTo(ip,port,data) 主动对某UDP服务发送数据 ip:ip地址,port:端口 data:数据ByteArray对象 true为发送成功 udpModule.connectSendTo("127.0.0.1",6060,byteArray)
sendData(socketid,ip,port,data) 发送数据 socketid:socket标示 data:string或者ByteArray true为成功 udpModule.sendData(socketid,ip,port,byteArray)
closeSocket(socketid) 关闭socket socketid:socket标示 true为成功 udpModule.closeSocket(socketid)
openLog(logname) 打开日至 在工程跟目录建立log目录 默认关闭,建议打开 日志文件名称 udpModule.openLog("serv")

setSocketAction,setThreadCount,setMaxConnectCount,setSockNormalBuflLen,addListenPort要在start之前调用。

·UdpModule 响应Action类可以有如下接口

function OnClose(sock)socket关闭

function OnRecv(sock,ip,port,byteArray,len)接收到数据。

这个方法会被多线程调用,如果要访问公共资源需要加锁。

·UdpModule 例子

服务器例子

  1. import CBSocket.code
  2. class UdpAction
  3. {
  4. var udpModule;
  5. function OnClose(sock)
  6. {
  7. print "onclose " + sock;
  8. }
  9. function OnRecv(sock,ip,port,byteArray,len)
  10. {
  11. print "onrecv " + sock + " " + ip + " " + port + " " + byteArray.readString() + " len:" + len;
  12. var byteArray = new ByteArray();
  13. byteArray.writeString("hello udp client");
  14. udpModule.sendData(sock,ip,port,byteArray);
  15. }
  16. }
  17. function main(parm)
  18. {
  19. var udpModule = new UdpModule();
  20. var udpAction = new UdpAction();
  21. udpAction.udpModule = udpModule;
  22. udpModule.setUdpAction(udpAction); //设置UDP处理类
  23. udpModule.start();
  24. udpModule.listen(6060); //监听6060端口
  25. udpModule.listen(6061,"*"); //监听6061端口,IPV4和IPV6兼容
  26. while(1) //主线程不能退出
  27. {
  28. Sleep(1000);
  29. }
  30. }

客户端例子

  1. import CBSocket.code
  2. class UdpAction
  3. {
  4. var udpModule;
  5. function OnClose(sock)
  6. {
  7. print "onclose " + sock;
  8. }
  9. function OnRecv(sock,ip,port,byteArray,len)
  10. {
  11. print "onrecv " + sock + " " + ip + " " + port + " " + byteArray.readString() + " len:" + len;
  12. }
  13. }
  14. function main(parm)
  15. {
  16. var udpModule = new UdpModule();
  17. var udpAction = new UdpAction();
  18. udpAction.udpModule = udpModule;
  19. udpModule.setUdpAction(udpAction); //设置TCP处理类
  20. udpModule.start();
  21. var byteArray = new ByteArray();
  22. byteArray.writeString("hello udp server");
  23. udpModule.connectSendTo("127.0.0.1",6060,byteArray);
  24. while(1) //主线程不能退出
  25. {
  26. Sleep(1000);
  27. }
  28. }

客户端结果如下:

  1. onrecv 131072 127.0.0.1 6060 hello udp client len:17

服务端结果如下:

  1. onrecv 131072 127.0.0.1 50332 hello udp server len:17