我用UDP接收一个工控设备发来的字符串,却怎么也接不到,厂家提供了一个C++原程序,可以跑通,怎么转成DELPHI就不行呢
很简单的一个例子:
放一个UDPCLIENT控件,设置HOST:='19.112.119.93'  PORT:=5555
然后SEND('*OPT?'),
再用IdUDPClient1.ReceiveString 取数据,总是报错说连接不上
错误提示代码是“socket error 10054 connect reset by peer.....”
补助说明:
1)远程IP,和PORT都是正确的,因为用厂商的源代码C++可以运行
2)我用软件模拟(在两台电脑上测试,一台当服务器,一台当客户端都能运行,)可是一连接到真正的硬件设备就说连不上远程主机,搞了一个礼拜了,
3)本机上没装杀毒软件,自带的防火墙也是关闭的
4)以下是厂商提供的部分源代码
...........socket初始化..定义..(略)
  char cBuffer[BUFFER_SIZE];
  sprintf(cBuffer, "*OPT?\n");
  MySend(sock, cBuffer); 
  recv(sock, cBuffer, sizeof(cBuffer),0);
  if (strstr(cBuffer,"DS") != NULL) {
    isDS = true;
  }
...........
5)本人程序部分代码
....
   UDPClient.Active:=false;
   UDPClient.Host:='19.112.119.93';
   UDPClient.port:=5555;
   UDPClient.Active:=true;
....
   UDPClient.send( '*OPT?');
   s:=receivestring(-2);
   if pos('DS',s)>0 then
     isDS := true;
.....
6)用端口查看器跟踪,执行本程序后会随机分配一个端口如1951,然后执行UDPClient初始化,会有一个程序定义的端口5555,执行数据send后又会多一个端口1952,,这个有什么参考价值吗?请做多udp直接连接硬件设备的同仁指点一下

解决方案 »

  1.   

    对了:
    还有个疑问,看了帮助文件receivestring()的参数,不管这么测试都不行
    function ReceiveString(const AMSec: Integer = IdTimeoutDefault): string; overload;
    function ReceiveString(var VPeerIP: string; var VPeerPort: integer; const AMSec: Integer = IdTimeoutDefault): string; overload;
    第一个函数好理解,只得一个参数,随便输个数值型就可
    第二个函数的参数,第一个参数ip地址,字符串型,第二个参数整形,端口值,第三个也是整形,
    可不管我怎么设置VPeerIP,VPeerPort,字符也罢,整数也罢,或只输一个,空一个也好,都说语法错误,正是搞不明白
      

  2.   

    以前我弄与收款机通讯没遇到你这问题啊,我的代码供参考:
    {设置}
    procedure TFrmMain.BtnSetClick(Sender: TObject);
    begin
      if (Edit3.Text = '') or (Edit1.Text = '')
        or (Edit2.Text = '') then
      begin
        MessageBox(HANDLE,'请将参数添加完整!','信息提示',MB_ICONWARNING + MB_OK);
        exit;
      end;
      IdUDPClient.Host := Trim(Edit3.Text);
      IdUDPClient.Port := StrToInt(Trim(Edit1.Text));
      IdUDPClient.ReceiveTimeout := RECIEVETIMEOUT;
      IdUDPServer.DefaultPort := StrToInt(Trim(Edit2.Text));
      IdUDPServer.Active := True;
      BtnSend.Enabled :=True;
    end;
    {接收数据}
    procedure TFrmMain.IdUDPServerUDPRead(Sender: TObject; AData: TStream;
      ABinding: TIdSocketHandle);
    var
      ReturnData: array[0..1024] of char;
    begin
      AData.Read(ReturnData,AData.Size);
      ReturnData[AData.Size] := #0;
      if self.CheckBox1.Checked then
        MReceivd.Lines.Clear;
      if RadioGroup1.ItemIndex = 0 then
        MReceivd.Lines.Add(ReturnData)
      else
        MReceivd.Lines.Add(Showstr(ReturnData,AData.Size));
    end;
      

  3.   

    最好把厂家代码发来看看,你这个问题就是端口UDP连接问题,没有连接上设备.
      

  4.   

    我用idTcpClient都可以连通,说明ip和端口都没问,只是后面的分析太复杂,没有头绪所以改用UDP,附上完成c++源码
    #include <stdio.h>
    #include <assert.h>
    #include <winsock2.h>
    #include <limits.h>
    #include "eb200udpsock.h"
    #define BUFFER_SIZE 100/* LOCAL DEFINES ***************************************************************/#define ASSERT  assert//#define SWAP#define HELP_NOTICE \
    "Usage:\n" \
    "  UDPEXAMPLE [OPTIONS] <device>\n" \
    "\n" \
    "  <device> Network name or IP address of receiver device.\n" \
    "\n" \
    "OPTIONS:\n" \
    "  -p <device IP port> TCP port of receiver device, defaults to 5555.\n" \
    "\n" \
    "  -am <audio mode> Audio mode. Refer to receiver manual for valid options.\n" \
    "         Defaults to 0 (no audio).\n" \
    "\n" \
    "  -af <audio file> Name of file for the audio data to be saved in .WAV format. \n" \
    "        If omitted, audio data will be forwarded to sound card, if installed.\n" \
    "\n" \
    "  -a    Audio only mode. All other datagrams will be ignored.\n" \
    "\n" \
    "  -c    Channels/sec statistics output only.\n" \
    "\n" \
    "  -iqm  Activates IQ data transmission.\n\n" \
    "  -iqf <IQ data file> Name of file for IQ data to be saved in stereo .WAV \n" \
    "        format. Recording will be abandoned if a sample rate changes occur.\n" \
    "        Implies -iqm.\n\n" \
    "  -iqfr <IQ data file> Name of file for IQ data to be saved in raw \n" \
    "        format. Recording will be abandoned if a sample rate changes occur.\n" \
    "        Implies -iqm.\n" \
    "\n" \
    "  Press any key to terminate UDPEXAMPLE. Don't use Ctrl-C, because this\n" \
    "  prevents UDPEXAMPLE from proper closing the dump files.\n"bool isEM050 = false;
    bool isDS = false;
    bool isPS = false;
    bool isFS = false;
    bool isCM = false;
    bool isSL = false;
    bool bChannelsOnly = false;/* FUNCTION ********************************************************************/
    int MySend(int sd, char *pBuffer)
    /*
    SPECIFICATION:
    Send String to socket sd
    PARAMETERS:
    int sd : socket descriptor
    char *pBuffer : Pointer to String
    PRECONDITIONS: 
    SIDE_EFFECTS: 
    RETURN_VALUES: 
    EXCEPTIONS: 
    ********************************************************************************/
    {
      unsigned int nLen;
      nLen = send(sd, pBuffer, strlen(pBuffer), 0);
      if (nLen != strlen(pBuffer))
      {
        printf("Error writing to socket. Len = %d\n", nLen);
      }
      return nLen;
    }/* GLOBAL FUNCTIONS DEFINITION *************************************************//* FUNCTION ********************************************************************/
    int main(int argc, char **argv)
    /*
    SPECIFICATION:  
      main function for this example
    PARAMETERS:
      int argc    : Number of command line arguments
      char **argv : Pointer to command line arguments
    PRECONDITIONS: 
    SIDE_EFFECTS: 
    RETURN_VALUES: 
    EXCEPTIONS: 
    ********************************************************************************/
    {
      bool bCmdLineOK = true;
      unsigned short usPort = 5555;
      unsigned unAudioMode = 0;
      char *pcWAVFile = NULL;
      bool bAudioOnlyMode = false;
      bool bIQMode = false;
      bool bRaw = false;
      char *pcIQFile = NULL;
      char *pcDeviceAddress = NULL;  /* Print banner */
      printf("UDPEXAMPLE 3.91, Copyright (c) 1998-2005 Rohde&Schwarz, Munich\n\n");  /* Process command line */
      int param;
      for (param = 1; param < argc && bCmdLineOK; ++param)
      {
        if (strcmp(argv[param], "-p") == 0)
        {
          /* Evaluate TCP port parameter */
          if (++param < argc)
          {
            unsigned unPort = atoi(argv[param]);
            usPort = (unsigned short) unPort;
            if (unPort > USHRT_MAX)
              bCmdLineOK = false;
          }
          else
            bCmdLineOK = false;
        }
        else if (strcmp(argv[param], "-am") == 0)
        {
          /* Evaluate audio mode parameter */
          if (++param < argc)
          {
            unAudioMode = atoi(argv[param]);
            if (unAudioMode > 12)
              bCmdLineOK = false;
          }
          else
            bCmdLineOK = false;
        }
        else if (strcmp(argv[param], "-af") == 0)
        {
          /* Evaluate audio file name */
          if (++param < argc)
          {
            pcWAVFile = argv[param];
            if (pcWAVFile[0] == '\0')
              bCmdLineOK = false;
    //        if (unAudioMode == 0)
    //          unAudioMode = 12;
          }
          else
            bCmdLineOK = false;
        }
        else if (strcmp(argv[param], "-a") == 0)
        {
          /* Evaluate audio only mode */
          bAudioOnlyMode = true;
        }
        else if (strcmp(argv[param], "-c") == 0)
        {
          /* Evaluate audio only mode */
          bChannelsOnly = true;
        }
        else if (strcmp(argv[param], "-iqm") == 0)
        {
          /* Evaluate IQ mode */
          bIQMode = true;
        }
        else if (strcmp(argv[param], "-iqf") == 0)
        {
          /* Evaluate IQ file name */
          if (++param < argc)
          {
            pcIQFile = argv[param];
            bIQMode = true;
            if (pcIQFile[0] == '\0')
              bCmdLineOK = false;
          }
          else
            bCmdLineOK = false;
        }
        else if (strcmp(argv[param], "-iqfr") == 0)
        {
          /* Evaluate IQ file name */
          if (++param < argc)
          {
            pcIQFile = argv[param];
            bIQMode = true;
            bRaw = true;
            if (pcIQFile[0] == '\0')
              bCmdLineOK = false;      }
          else
            bCmdLineOK = false;
        }
        else if (param == argc-1)
        {
          /* Evaluate receiver device address */
          pcDeviceAddress = argv[argc-1];
        }
        else
          bCmdLineOK = false;
      }  /* Output help text if no command line parameter given or command line faulty */
      if (!bCmdLineOK || pcDeviceAddress == NULL)
      {
        printf(HELP_NOTICE);
        return 1;
      }  /* Determine receiver device IP address */
      unsigned long ulRemoteAddress = inet_addr(pcDeviceAddress);
      if (ulRemoteAddress == INADDR_NONE)
      {
        hostent* phost = gethostbyname(pcDeviceAddress);
        if (phost && phost->h_addr_list[0] != NULL)
          ulRemoteAddress = *((unsigned*) phost->h_addr_list[0]);
        else
        {
          printf("Can't resolve host name %s.\n", pcDeviceAddress);
          return 1;
        }
      }  WSADATA wsaData;
      if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
      {
        /* Tell the user that we couldn't find a usable */
        /* WinSock DLL.                  */
        printf("Error retrieving windows socket dll.\n");
        return 1;
      }
     
     
      if ( LOBYTE(wsaData.wVersion) != 2 ||
          HIBYTE(wsaData.wVersion) != 0 ) {
        /* Tell the user that we couldn't find a usable */
        /* WinSock DLL.                  */
        printf("Error retrieving correct winsock version 2.0.\n");
        WSACleanup();
        return 1; 
      }
      /* The WinSock DLL is acceptable. Proceed. */
     
      /* Create a TCP receiver command socket */
      SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
      if (sock == -1)
      {
        printf("Error creating socket.\n");
        return 1;
      }  /* Create socket address structure for INET address family */
      struct sockaddr_in addrDevice;
      memset(&addrDevice, 0, sizeof(addrDevice));
      addrDevice.sin_family      = AF_INET;
      addrDevice.sin_addr.s_addr = ulRemoteAddress;
      addrDevice.sin_port        = htons(usPort);  /* connect socket to receiver device */
      if (connect(sock, (struct sockaddr *)&addrDevice, sizeof(addrDevice)) != 0)
      {
        printf("Error connecting to %s\n", pcDeviceAddress);
        return 1;
      }  /* successful connection 
       * create UDP socket instance */
      CEB200UdpSock ctSock;  /* do some UDP configuration
       * retrieve our IP address */
      struct sockaddr_in addrLocal;
      int addrlen = sizeof(addrLocal);
      getsockname(sock, (struct sockaddr*)&addrLocal, &addrlen);
      char *pIP = inet_ntoa(addrLocal.sin_addr);  char cBuffer[BUFFER_SIZE];
      sprintf(cBuffer, "*OPT?\n");
      MySend(sock, cBuffer); 
      recv(sock, cBuffer, sizeof(cBuffer),0);
      if (strstr(cBuffer,"DS") != NULL) {
        isDS = true;
      }
      

  5.   

    最主要就是上面结尾部分,下面补全
      MySend(sock, "*IDN?\n"); 
      recv(sock, cBuffer, sizeof(cBuffer),0);
      if (strstr(cBuffer,"EM050") != NULL) {
        isEM050 = true;
      }  /* If no multi-access to receiver device required
       * delete all upd paths */
      sprintf(cBuffer, "TRAC:UDP:DEL ALL\n");
      MySend(sock, cBuffer);  /* Check if udp path available */
    /*
      int status;
      sprintf(cBuffer, "TRAC:UDP:TAG \"%s\", %d, FSC\n", pIP, ctSock.GetUdpPort());
      MySend(sock, cBuffer);
      MySend(sock, "SYST:ERR?");
      MyRecv(sock, cBuffer, 1);
      sscanf(cBuffer, "%d", &status);
      if (status != 0)
      {
        printf("No trace available in receiver device: %s", cBuffer);
        return 1;
      }
      sprintf(cBuffer, "TRAC:UDP:TAG:OFF \"%s\", %d, FSC\n", pIP, ctSock.GetUdpPort());
      MySend(sock, cBuffer);
    */  
      /* Configure receiver device traces */
      if (!bAudioOnlyMode)
      {
        sprintf(cBuffer, "TRAC:UDP:TAG \"%s\", %d, FSC, MSC, DSC, AUD, IFP, CW\n", pIP, ctSock.GetUdpPort());
        MySend(sock, cBuffer); 
        if (isCM) {
          sprintf(cBuffer, "TRAC:UDP:TAG \"%s\",%d, FAST, LIST\n", pIP, ctSock.GetUdpPort());
          MySend(sock, cBuffer); 
        }
        if (isEM050) {
            if (isSL)
            {
                sprintf(cBuffer, "TRAC:UDP:TAG \"%s\", %d, IF, VID, VDP, PSC, SELC\n", pIP, ctSock.GetUdpPort());
            }
            else
            {
                sprintf(cBuffer, "TRAC:UDP:TAG \"%s\", %d, IF, VID, VDP, PSC\n", pIP, ctSock.GetUdpPort());
            }      MySend(sock, cBuffer); 
        }
        sprintf(cBuffer, "TRAC:UDP:FLAG \"%s\", %d, \"VOLT:AC\", \"FREQ:RX\", \"FREQ:OFFSET\", \"OPT\"\n", pIP, ctSock.GetUdpPort());
        MySend(sock, cBuffer);
        if (isFS) {
          sprintf(cBuffer, "TRAC:UDP:FLAG \"%s\", %d, \"FSTRength\"\n", pIP, ctSock.GetUdpPort());
          MySend(sock, cBuffer); 
          // and also set up the appropriate sensor function
          MySend(sock, "SENS:FUNC 'FSTR'\n"); 
        }
    #ifdef SWAP
                    sprintf(cBuffer, "TRAC:UDP:FLAG \"%s\",%d,\"SWAP\"\n", pIP, pSock->GetUdpPort());
                    MySend(m_nSocketID, cBuffer);
    #endif
      }
      else
      {
        sprintf(cBuffer, "TRAC:UDP:TAG \"%s\", %d, AUDIO\n", pIP, ctSock.GetUdpPort());
        MySend(sock, cBuffer); 
        sprintf(cBuffer, "TRAC:UDP:FLAG \"%s\", %d, \"OPT\"\n", pIP, ctSock.GetUdpPort());
        MySend(sock, cBuffer); 
      }  /* configure audio mode */
      sprintf(cBuffer, "SYST:AUD:REM:MODE %d\n", unAudioMode);
      MySend(sock, cBuffer);  if (isEM050)
      {
          /* configure IQ data mode */
          sprintf(cBuffer, "SYST:IF:REM:MODE %s\n", (bIQMode? "SHORT" : "OFF"));
          MySend(sock, cBuffer);
      }  /* IQ File Recording? */
      if (pcIQFile)
      {
    ctSock.SetIFRecording(pcIQFile, bRaw);
      }  /* WAV File Recording? */
      if (pcWAVFile)
      {
        ctSock.SetAFRecording(pcWAVFile);
      }  /* call socket reception routine */
      ctSock.Init();  /* stop data transfer from receiver device */
      sprintf(cBuffer, "TRAC:UDP:DEL \"%s\", %d\n", pIP, ctSock.GetUdpPort());
      MySend(sock, cBuffer);   return 0;
    }/* FUNCTION ********************************************************************/
    bool EquipmentisEM050(void)
    /*
    SPECIFICATION:
    PARAMETERS:
    void : 
    PRECONDITIONS: 
    SIDE_EFFECTS: 
    RETURN_VALUES: 
    EXCEPTIONS: 
    ********************************************************************************/
    {
      return(isEM050);
    }/* FUNCTION ********************************************************************/
    bool OptionisDS(void)
    /*
    SPECIFICATION:
    PARAMETERS:
    void : 
    PRECONDITIONS: 
    SIDE_EFFECTS: 
    RETURN_VALUES: 
    EXCEPTIONS: 
    ********************************************************************************/
    {
      return(isDS);
    }/* FUNCTION ********************************************************************/
    bool OptionisPS(void)
    /*
    SPECIFICATION:
    PARAMETERS:
    void : 
    PRECONDITIONS: 
    SIDE_EFFECTS: 
    RETURN_VALUES: 
    EXCEPTIONS: 
    ********************************************************************************/
    {
      return(isPS);
    }/* FUNCTION ********************************************************************/
    bool OptionisFS(void)
    /*
    SPECIFICATION:
    PARAMETERS:
    void : 
    PRECONDITIONS: 
    SIDE_EFFECTS: 
    RETURN_VALUES: 
    EXCEPTIONS: 
    ********************************************************************************/
    {
      return(isFS);
    }/* FUNCTION ********************************************************************/
    bool OptionisCM(void)
    /*
    SPECIFICATION:
    PARAMETERS:
    void : 
    PRECONDITIONS: 
    SIDE_EFFECTS: 
    RETURN_VALUES: 
    EXCEPTIONS: 
    ********************************************************************************/
    {
      return(isCM);
    }/* FUNCTION ********************************************************************/
    bool ChannelsOnly(void)
    /*
    SPECIFICATION:
    PARAMETERS:
    void : 
    PRECONDITIONS: 
    SIDE_EFFECTS: 
    RETURN_VALUES: 
    EXCEPTIONS: 
    ********************************************************************************/
    {
      return(bChannelsOnly);
    }编译这段代码:实行执行UdpExample.exe 19.112.119.93 结果就会显示出出来,dos下的 
      

  6.   

    代码太长了没时间去看,用WPE看看就知道他的这个C代码是如何和硬件通讯的了,代码或许都不用看.
      

  7.   

    不用看他的代码,我现在的问题很简单就是连接设备出错,
    下面是我的代码
    procedure TForm1.Button8Click(Sender: TObject);
    var
      i,j:integer;
      s,t,s1:string;
      Stream1:TstringStream;
      DList:TStringList; err:integer;
      //cBuffer[200]:char;
    bSrq:boolean;  nStb:integer;
      sSRE:string;
    begin
      try
        Stream1:=TStringStream.Create('');    UDPClient.Active:=false;
        UDPClient.Host:=edit8.Text;//19.112.119.93
        UDPClient.port:=strtoint(combobox1.Text);//5555
        UDPClient.Active:=true;
        if UDPClient.Active=true then
          memo2.text:='udp connected'
        else
          begin
            memo2.text:='udp connected error';
            //exit;
          end;    with UDPclient do
          begin
            try
              memo2.Lines.Add('准备发送数据!');          send( '*OPT?');
              s:=receivestring(-2);          if pos('DS',s)>0 then
                isDS := true;
              if pos('PS',s)>0  then
                isPS := true;
              if pos('FS',s)>0  then
                isFS := true;
              if pos('CM',s)>0  then
                isCM := true;
              if pos('SL',s)>0  then
                isSL := true;          send( '*IDN?');
              memo2.Lines.Add('*IDN? ...sended...'+FormatDateTime('hh:mm:ss:zzz',now));
              s:=receivestring(1000);
              memo2.Lines.Add('receive....'+FormatDateTime('hh:mm:ss zzz',now)+' '+s);          if pos('EM050',s)>0 then
                isEM050 := true;
              if pos('EM550',s)>0 then
                isEM050 := true;
              if pos('EM510',s)>0 then
                isEM050 := true;
             except
                memo2.Lines.Add('发送数据失败!');
             end;//end try
          end;//end with
      finally
        Stream1.Free;
      end;end;
    执行到reveivestring就出错
      

  8.   

    不用看他的代码,我现在的问题很简单就是连接设备出错, 
    就叫你用WPE看看包,是不是他又另开个端口发送数据.
      

  9.   

    我也奇怪,跟踪到他有一个端口是getudpport()=19001,还有其他几个端口号,难道udp要几个端口才能完成传送和接收,
    正如我前面提到,我的delphi执行过程也跟踪到3个端口
      

  10.   

    用WEP分析啊.看看什么数据发什么端口.
      

  11.   

    楼上兄弟:非常感谢您的支持!
    说明文档说的很清楚,tcp和udp都用5555这个端口通讯,而且我用idtcpclient都调试通了,说明就是这个端口其作用,WEP这个东东没用过:(
      

  12.   

    路过的朋友帮帮手,能否给你一个idudp连接硬件的例子,udp解释的很简单,就这么三句话,折腾我一个礼拜了,是不是从没有有人调试成功过,所以没人用这玩意,谁能帮看看那个破函数也成
    还有个疑问,看了帮助文件receivestring()的参数,不管这么测试都不行 
    function ReceiveString(var VPeerIP: string; var VPeerPort: integer; const AMSec: Integer = IdTimeoutDefault): string; overload; 
    第一个参数ip地址,字符串型,第二个参数整形,端口值,第三个也是整形, 
    可不管我怎么设置VPeerIP,VPeerPort,字符也罢,整数也罢,或只输一个,空一个也好,都说语法错误,正是搞不明白,打算改行java了,delphi估计也快走到尽头了 
      

  13.   

    to:2楼的兄台,你的关键部分没看到,怎么发送数据的?初始化IdUDPClient以后,要向收银机发指令呀,否则怎么沟通
      IdUDPClient.Host := Trim(Edit3.Text); 
      IdUDPClient.Port := StrToInt(Trim(Edit1.Text)); 
      IdUDPClient.ReceiveTimeout := RECIEVETIMEOUT;
      //IdUDPClient属性配置 
     
      IdUDPServer.DefaultPort := StrToInt(Trim(Edit2.Text)); 
      IdUDPServer.Active := True;
      //IdUDPServer启动监听 
      你的接受是直接用udpserver来监听的,能否不用牠直接用IdUDPClient.receivestring来收呢
      可否告知你的qq,方便时候联系,我的qq是:8585302
      

  14.   

    发送代码:
    procedure TFrmMain.BtnSendClick(Sender: TObject);
    var
      SendData: string;
    begin
      if RadioGroup2.ItemIndex = 0 then
        SendData := Trim(EdtCommand.Text)
      else
        SendData := HexToString(Cutblank_wanjun(Trim(EdtCommand.Text)));
      if CheckBox2.Checked then
         SendData := SendData + hextostring(inttohex(crc16(SendData,length(SendData)),4));
      IdUDPClient.Send(SendData);
    end;
      

  15.   

    有没有send以后直接用receivestring的实例呢?如果用两台电脑模拟没问题,一连接硬件就不行,请大家再不要怀疑硬件端口,ip地址是否正确,用厂家提供程序可以跑通的,主要是udplicnet用法还有那些隐含的注意事项,或限制