non-blocking mode in tcpip

leon517
2016-05-24
2018-01-29
  • leon517 - 2016-05-24

    PROGRAM TcpServer
    VAR_INPUT
    nTcp : INT;
    Rcv : FB_Fifo999;
    sIP : STRING(255) := '192.168.1.11';
    IPport : WORD := 5555;
    tDelay : TIME := T#100MS;
    END_VAR
    VAR_OUTPUT
    AcceptHl : DINT;
    cnt : BOOL;
    END_VAR
    VAR
    ListenHl,Hl : DINT;
    Rv0 : BOOL;
    ServerAds,AcceptAds : SOCKADDRESS;
    ClienSize : DWORD;
    sRcv : STRING(255);
    RcvNum : DINT;
    nNum,n1 : UINT;
    bHead : ARRAY [0..5] OF BYTE;
    END_VAR

    CASE nTcp OF
    0://Create handle
    ListenHl := SysSockCreate(SOCKET_AF_INET, SOCKET_STREAM,SOCKET_IPPROTO_TCP );
    IF ListenHl <> 0 THEN
    nTcp := nTcp + 1;
    ELSE
    nTcp := -1;//create socket error
    END_IF
    1://Convert IP
    ServerAds.sin_addr := SysSockInetAddr(sIP);
    ServerAds.sin_port := SysSockHtons(IPport);
    ServerAds.sin_family := SOCKET_AF_INET;
    nTcp := nTcp + 1;
    2://Bind Ip
    Rv0 := SysSockBind(ListenHl,ADR(ServerAds),SIZEOF(ServerAds));
    IF Rv0 THEN
    nTcp := nTcp + 1;
    ELSE
    nTcp := -2;//Blind ip error
    // nTcp := 18;//Blind ip error
    END_IF
    3://Create listenhandle
    Rv0 := SysSockListen(ListenHl , 0 );
    IF Rv0 THEN
    nTcp := nTcp + 1;
    ELSE
    nTcp := -3;//listen error
    // nTcp := 18;//listen error
    END_IF
    4://Accept Client
    AcceptHl := SysSockAccept(ListenHl, ADR(AcceptAds),ADR(ClienSize));
    IF AcceptHl > 0 THEN
    SysSockClose(ListenHl);
    cnt := TRUE;
    nTcp := nTcp + 1;
    END_IF
    END_CASE

    //*****Question*********
    The socket is basically created and exploited in the blocking mode. This may cause trouble in PLC
    application because the program will stop on the function call where it waits the function finished.
    By default, the call of socket function could be blocking for the following “TCP oriented” functions:
    SysSockRecv(), SysSockSend(),SysSockConnect(), SysSockAccept(),SysSockClose();

    Theoretically, in Data Transfer phase of the TCP connection, the order of call of functions Send() and
    Recv() doesn't matter. But, for the same process (task), the sequence:
    SysSockRecv();
    SysSockSend();
    could be critical. The program will not be able to send something if before, it does not receive something.

    //*****Question*********
    There are different ways to solve this problem in the PLC application:
    1. The use of one task for PLC control and some several separate tasks for socket and
    communication handling
    2. Changing of the socket mode into no blocking mode via function SysSockIoctl()
    3. The use the function SysSockSelect()

    I tryed the first way using separate tasks and it works.But when there are many clients,it is not good enough.
    What I want to know:How to use the way2 and way3?
    Would any guys provide code basically on mine?

     
  • leon517 - 2016-05-25
     
  • leon517 - 2016-05-26
     
  • leon517 - 2016-06-02
     
  • danyamian - 2018-01-29

    leon517 hat geschrieben:
    PROGRAM TcpServer
    VAR_INPUT
    nTcp : INT;
    Rcv : FB_Fifo999;
    sIP : STRING(255) := '192.168.1.11';
    IPport : WORD := 5555;
    tDelay : TIME := T#100MS;
    END_VAR
    VAR_OUTPUT
    AcceptHl : DINT;
    cnt : BOOL;
    END_VAR
    VAR
    ListenHl,Hl : DINT;
    Rv0 : BOOL;
    ServerAds,AcceptAds : SOCKADDRESS;
    ClienSize : DWORD;
    sRcv : STRING(255);
    RcvNum : DINT;
    nNum,n1 : UINT;
    bHead : ARRAY [0..5] OF BYTE;
    END_VAR
    CASE nTcp OF
    0://Create handle
    ListenHl := SysSockCreate(SOCKET_AF_INET, SOCKET_STREAM,SOCKET_IPPROTO_TCP );
    IF ListenHl <> 0 THEN
    nTcp := nTcp + 1;
    ELSE
    nTcp := -1;//create socket error
    END_IF
    1://Convert IP
    ServerAds.sin_addr := SysSockInetAddr(sIP);
    ServerAds.sin_port := SysSockHtons(IPport);
    ServerAds.sin_family := SOCKET_AF_INET;
    nTcp := nTcp + 1;
    2://Bind Ip
    Rv0 := SysSockBind(ListenHl,ADR(ServerAds),SIZEOF(ServerAds));
    IF Rv0 THEN
    nTcp := nTcp + 1;
    ELSE
    nTcp := -2;//Blind ip error
    // nTcp := 18;//Blind ip error
    END_IF
    3://Create listenhandle
    Rv0 := SysSockListen(ListenHl , 0 );
    IF Rv0 THEN
    nTcp := nTcp + 1;
    ELSE
    nTcp := -3;//listen error
    // nTcp := 18;//listen error
    END_IF
    4://Accept Client
    AcceptHl := SysSockAccept(ListenHl, ADR(AcceptAds),ADR(ClienSize));
    IF AcceptHl > 0 THEN
    SysSockClose(ListenHl);
    cnt := TRUE;
    nTcp := nTcp + 1;
    END_IF
    END_CASE
    //*****Question********
    The socket is basically created and exploited in the blocking mode. This may cause trouble in PLC
    application because the program will stop on the function call where it waits the function finished.
    By default, the call of socket function could be blocking for the following “TCP oriented” functions:
    SysSockRecv(), SysSockSend(),SysSockConnect(), SysSockAccept(),SysSockClose();
    Theoretically, in Data Transfer phase of the TCP connection, the order of call of functions Send() and
    Recv() doesn't matter. But, for the same process (task), the sequence:
    SysSockRecv();
    SysSockSend();
    could be critical. The program will not be able to send something if before, it does not receive something.
    //*****Question********

    There are different ways to solve this problem in the PLC application:
    1. The use of one task for PLC control and some several separate tasks for socket and
    communication handling
    2. Changing of the socket mode into no blocking mode via function SysSockIoctl()
    3. The use the function SysSockSelect()
    I tryed the first way using separate tasks and it works.But when there are many clients,it is not good enough.
    What I want to know:How to use the way2 and way3?
    Would any guys provide code basically on mine?

    Hi, I'm working on a similar project. I have a raspberry in which I need to run a TCP server where I will receive messages from clients by sockets. I can not get it to work properly, have you managed to get it to work properly? Do you have more information on the server?

    Thank you very much.

     

Log in to post a comment.