Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi与Java的Socket通信_Java_Sockets_Delphi - Fatal编程技术网

Delphi与Java的Socket通信

Delphi与Java的Socket通信,java,sockets,delphi,Java,Sockets,Delphi,我想在本地主机上创建Delphi6和Eclipse之间的套接字通信。Delphi代码似乎可以工作,我可以将数据从Delphi服务器发送到Delphi客户端。现在我想将数据从同一个Delphi服务器发送到Java客户端。下面是我从几个示例中使用的代码。Delphi和Java之间的连接似乎已经建立,但在while循环(stdIn.readLine())中,程序不再工作。也不例外。程序只是停止工作。如何从Delphi服务器读取数据 谢谢 import java.io.BufferedReader; i

我想在本地主机上创建Delphi6和Eclipse之间的套接字通信。Delphi代码似乎可以工作,我可以将数据从Delphi服务器发送到Delphi客户端。现在我想将数据从同一个Delphi服务器发送到Java客户端。下面是我从几个示例中使用的代码。Delphi和Java之间的连接似乎已经建立,但在while循环(stdIn.readLine())中,程序不再工作。也不例外。程序只是停止工作。如何从Delphi服务器读取数据

谢谢

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class JavaClientSocketEx {
    public static void main(String[] args) {
        try {
            Socket echoSocket = new Socket("127.0.0.1", 10003);
            PrintWriter out =
                new PrintWriter(echoSocket.getOutputStream(), true);
            BufferedReader in =
                new BufferedReader(
                    new InputStreamReader(echoSocket.getInputStream()));
            BufferedReader stdIn =
                new BufferedReader(
                    new InputStreamReader(System.in));
            String userInput;
            echoSocket.close();
            while ((userInput = stdIn.readLine()) != null) { // at this point the programm doesnt work anymore!
                out.println(userInput);
                System.out.println("echo: " + in.readLine());
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
}
编辑:Delphi代码

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, ExtCtrls, StdCtrls;

type
  CustomRec = record
    Zahl: byte;
end;
TForm1 = class(TForm)
    Edit1: TEdit;
    Timer1: TTimer;
    sendenButton: TButton;
    Edit2: TEdit;
    ClientSocket1: TClientSocket;
    ServerSocket1: TServerSocket;
    procedure Timer1Timer(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure sendenButtonClick(Sender: TObject);
    procedure ServerSocket1ClientError(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
      ErrorEvent: TErrorEvent; var ErrorCode: Integer);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  senden : boolean;

implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
var
text : string;
begin

        text :=  Edit1.Text;
        ClientSocket1.Socket.SendText(text);

end;

procedure TForm1.FormActivate(Sender: TObject);
begin
        sendenButton.Caption := 'Send';
        senden := false;
        ClientSocket1.Port := 10003;
        ClientSocket1.Host := '127.0.0.1';
        ClientSocket1.Active := true;
        ServerSocket1.Port := 10003;
        ServerSocket1.Active := true;

end;

procedure TForm1.sendenButtonClick(Sender: TObject);
begin

  if senden then
   begin
        senden := false;
        sendenButton.Caption := 'Send';
        Timer1.Enabled := false;
   end
  else
   begin
        senden :=true;
        sendenButton.Caption := 'Stopp';
        Timer1.Enabled := true;
  end;
end;

procedure TForm1.ServerSocket1ClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
Errorcode := 0;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var  Rec: CustomRec;
begin
     edit2.Text := Socket.ReceiveText;
     rec.Zahl:=StrToInt(Edit2.Text);
     Socket.SendBuf(Rec,sizeof(Rec));
end;

procedure TForm1.ClientSocket1Error(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
Errorcode :=0;
end;

end.
在我点击“sendenButton”后,delphi客户端在一秒钟的时间间隔内开始周期性地从第一个编辑元素(即输入)发送数据。第二个编辑元素是接收数据的输出。我再次单击此按钮后,它停止发送

  • 问题可能出现在
    while
    循环中,您试图在已关闭的套接字上读写

    echoSocket.close();
    while ((userInput = stdIn.readLine()) != null) { // at this point the programm doesnt work anymore!
      out.println(userInput);
      . . .
    
    这可以通过移动
    echoSocket.close()来解决在循环之后。
    之后,Java客户端工作;现在问题出在服务器上

  • Delphi客户端绑定到服务器,优先级高于Java客户端。
    要解决此问题,请禁用Delphi客户端:

    //ClientSocket1.Active := true;
    
    之后,服务器工作

  • 此时,当您通过控制台发送号码时,例如
    42
    ,服务器会引发异常:

    Project 1.exe引发异常类EConvertError,消息为“42
    '不是有效的整数值'

    问题发生在
    serversocket1clienttread
    m方法中,使用以下指令:

    rec.Zahl := StrToInt(Edit2.Text);
    
    因为socket接收到的字符串是

    '42'#$D#$A
    
    你可以考虑对课文进行消毒:

    rec.Zahl := StrToInt(StringReplace(Trim(Edit2.Text), '''', '', [rfReplaceAll]));
    
  • 向客户端发送回复时,消息终止符
    \$D\$A
    丢失。线路

    Socket.SendBuf(Rec, sizeof(Rec));
    
    必须像这样改变

    Socket.SendText(IntToStr(rec.Zahl) + #13#10);
    
    这就解决了阻塞客户端的问题


  • 编辑后的程序如下-我已将逻辑从
    OnActivate
    移动到
    OnCreate
    表单事件:

    Delphi服务器/客户端

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ScktComp, ExtCtrls, StdCtrls;
    
    type
      CustomRec = record
        Zahl: Byte;
      end;
    
    TForm1 = class(TForm)
      Edit2: TEdit;
        Edit1: TEdit;
        sendenButton: TButton;
      procedure ServerSocket1ClientError(Sender: TObject;
        Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
        var ErrorCode: Integer);
      procedure ServerSocket1ClientRead(Sender: TObject;
        Socket: TCustomWinSocket);
      procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
        ErrorEvent: TErrorEvent; var ErrorCode: Integer);
      procedure FormCreate(Sender: TObject);
        procedure sendenButtonClick(Sender: TObject);
    private
      { Private-Deklarationen }
      ClientSocket1: TClientSocket;
      ServerSocket1: TServerSocket;
    public
      { Public-Deklarationen }
    end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ClientSocket1 := TClientSocket.Create(Self);
      ClientSocket1.OnError := ClientSocket1Error;
    
      ServerSocket1 := TServerSocket.Create(Self);
      ServerSocket1.OnClientError := ServerSocket1ClientError;
      ServerSocket1.OnClientRead := ServerSocket1ClientRead;
    
      ClientSocket1.Port := 10003;
      ClientSocket1.Host := '127.0.0.1';
      //ClientSocket1.Open;
    
      ServerSocket1.Port := 10003;
      ServerSocket1.Open;
    end;
    
    procedure TForm1.sendenButtonClick(Sender: TObject);
    begin
      sendenButton.Enabled := False;
      ClientSocket1.Open;
      ClientSocket1.Socket.SendText(Edit1.Text);
      ClientSocket1.Close;
      sendenButton.Enabled := True;
    end;
    
    procedure TForm1.ServerSocket1ClientError(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    begin
      Errorcode := 0;
    end;
    
    procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
    var
      rec: CustomRec;
      sInt, reply: string;
      iInt, iCode: Integer;
    begin
      edit2.Text := Socket.ReceiveText;
    
      sInt := StringReplace(Trim(Edit2.Text), '''', '', [rfReplaceAll]);
      Val(sInt, iInt, iCode);
    
      if iCode = 0 then begin
        if iInt in [Low(Byte)..High(Byte)] then begin
          rec.Zahl := iInt;
          reply := IntToStr(rec.Zahl);
        end;
      end
      else
        reply := '-1';
    
      Socket.SendText(reply + #13#10);
    end;
    
    procedure TForm1.ClientSocket1Error(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    begin
      Errorcode := 0;
    end;
    
    end.
    
    Java客户端

    public static void main(String[] args) throws UnknownHostException, IOException {
    
        Socket echoSocket = new Socket("127.0.0.1", 10003);
        try {
            PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
            BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
            String userInput;
    
            while ((userInput = stdIn.readLine()) != null) {
    
                //the next 2 lines resume like: if you have to die, die fast
                int value = Integer.parseInt(userInput);//ensure that input is an Integer
                assert (value >= 0 && value <= 255);// ensure that the Integer is in the Delphi's Byte range
    
                out.println(value);
    
                System.out.println("server replies: " + in.readLine());
            }
        } finally {
            echoSocket.close();
        }            
    }
    


    现在我找到了解决问题的办法。非常感谢你的建议,fantaghirocco,它帮助我找到了答案。我似乎不理解服务器-客户机体系结构的原理。我修改了你的代码,现在对我来说很好

    Delphi代码:

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ScktComp, ExtCtrls, StdCtrls;
    
    type
      CustomRec = record
        Zahl: Byte;
      end;
    
    TForm1 = class(TForm)
        edit1: TEdit;
        ClientSocket1: TClientSocket;
        ServerSocket1: TServerSocket;
        Label1: TLabel;
      procedure ServerSocket1ClientError(Sender: TObject;
        Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
        var ErrorCode: Integer);
      procedure MyServerSocket1ClientRead(Sender: TObject;
        Socket: TCustomWinSocket);
      procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
        ErrorEvent: TErrorEvent; var ErrorCode: Integer);
        procedure FormActivate(Sender: TObject);
    private
    public
      { Public-Deklarationen }
    end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    
    procedure TForm1.ServerSocket1ClientError(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    begin
      Errorcode := 0;
    end;
    
    procedure TForm1.MyServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
    var
      rec: CustomRec;
      sInt, reply: string;
      iInt, errorPos: Integer;
    begin
      edit1.Text := Socket.ReceiveText;
    
      sInt := StringReplace(Trim(Edit1.Text), '''', '', [rfReplaceAll]);
      Val(sInt, iInt, errorPos);
    
      if errorPos = 0 then begin
        if iInt in [Low(Byte)..High(Byte)] then begin
          rec.Zahl := iInt;
          iInt := iInt +1;
          reply := IntToStr(rec.Zahl);
        end;
      end
      else
        reply := '-1';
        reply := 'reply ' + reply + ' accepted';
      Socket.SendText(reply + #13#10);
    end;
    
    procedure TForm1.ClientSocket1Error(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    begin
      Errorcode := 0;
    end;
    
    procedure TForm1.FormActivate(Sender: TObject);
    begin
      ClientSocket1 := TClientSocket.Create(Self);
      ClientSocket1.OnError := ClientSocket1Error;
    
      ServerSocket1 := TServerSocket.Create(Self);
      ServerSocket1.OnClientError := ServerSocket1ClientError;
      ServerSocket1.OnClientRead := MyServerSocket1ClientRead;
    
      ClientSocket1.Port := 10003;
      ClientSocket1.Host := '127.0.0.1';
    
      ServerSocket1.Port := 10003;
      ServerSocket1.Open;
    end;
    
    end.
    
    德尔菲表格:

    Java代码:

    class TCPClient {
        private static int input;
    public static void main(String[] args) throws UnknownHostException, IOException {
    
        Socket echoSocket = new Socket("127.0.0.1", 10003);
        Timer timer = new Timer();
        input = 0;
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    input = input +1;
                    doTime(echoSocket, input);
                } catch (IOException e) {
                    e.printStackTrace();
                }  
            }
        }, 1000,1000);   
    }
    
    private static void doTime(Socket echoSocket, int input) throws IOException {
        try {
            PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
            //the next 2 lines resume like: if you have to die, die fast
            int value = input;//ensure that input is an Integer
            assert (value >= 0 && value <= 255);// ensure that the Integer is in the Delphi's Byte range
            System.out.println("sending server reply number : " + value);
            out.println(value);
            System.out.println("server replies: " + in.readLine());
    
        } finally {
            //  echoSocket.close();
        }
    }
    
    类TCPClient{
    私有静态int输入;
    公共静态void main(字符串[]args)抛出UnknownHostException、IOException{
    插座echoSocket=新插座(“127.0.0.1”,10003);
    定时器=新定时器();
    输入=0;
    timer.schedule(新TimerTask(){
    @凌驾
    公开募捐{
    试一试{
    输入=输入+1;
    doTime(echoSocket,输入);
    }捕获(IOE异常){
    e、 printStackTrace();
    }  
    }
    }, 1000,1000);   
    }
    私有静态void doTime(套接字echoSocket,int输入)引发IOException{
    试一试{
    PrintWriter out=新的PrintWriter(echoSocket.getOutputStream(),true);
    BufferedReader in=新的BufferedReader(新的InputStreamReader(echoSocket.getInputStream());
    //接下来的两行是这样继续的:如果你不得不死,那就赶快死吧
    int value=input;//确保输入为整数
    
    assert(value>=0&&value您能用Delphi服务器完成您的问题并详细说明“停止工作”的概念吗?我的意思是:发生异常或者
    userInput
    立即为
    null
    系统。如果您想输出套接字输入,
    BufferedReader stdIn=new BufferedReader,我觉得在
    中很奇怪(新建InputStreamReader(System.in));
    没有例外。在调试模式下,第“userInput=stdIn.readLine()”行的程序似乎已经完成。我还尝试了其他解决方案,例如:。但在“String str=in.readLine()”处也存在同样的问题但是您正在等待
    系统。在
    中,不是等待套接字,而且在我看来,套接字没有绑定到
    系统。在
    中,是吗?我不了解两者之间的关系,抱歉=:-)我知道您的意思,但当我删除“System.in”:socket echosket=新套接字(“127.0.1”,10003)时,这也不起作用;PrintWriter out=new PrintWriter(echoSocket.getOutputStream(),true);BufferedReader in=new BufferedReader(new InputStreamReader(echoSocket.getInputStream());String userInput;//echoSocket.close();while((userInput=in.readLine())!=null){out.println(userInput);System.out.println(“echo:+in.readLine());}与以前相同的问题。调试器显示了以下内容(图):似乎有一个循环谢谢你的建议Fantagirocco,但它仍然不起作用。我没有得到任何Java流。但是delphi和Java之间有一个连接。如果我退出Java程序,delphi服务器会以“eSocketeror10053”中断。因此,我认为代码中仍然存在一个小错误。我只想在不使用文本文件的情况下将数据从delphi发送到java;)有人能帮我吗?我很抱歉,5个月前我粘贴了一个错误的单元!我用正确的Delphi代码再次编辑了答案。经过重新测试,以上方法对我有效。用法:1)启动Delphi服务器2)启动java客户端3)在java控制台中输入一个数字-使用回车发送Delphi客户端有一些小问题,但重点是Delphi服务器和Java客户端之间的通信对我来说仍然不起作用。出现异常:在线程“main”Java.net中。ConnectException:连接被拒绝:连接。
    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ScktComp, ExtCtrls, StdCtrls;
    
    type
      CustomRec = record
        Zahl: Byte;
      end;
    
    TForm1 = class(TForm)
        edit1: TEdit;
        ClientSocket1: TClientSocket;
        ServerSocket1: TServerSocket;
        Label1: TLabel;
      procedure ServerSocket1ClientError(Sender: TObject;
        Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
        var ErrorCode: Integer);
      procedure MyServerSocket1ClientRead(Sender: TObject;
        Socket: TCustomWinSocket);
      procedure ClientSocket1Error(Sender: TObject; Socket: TCustomWinSocket;
        ErrorEvent: TErrorEvent; var ErrorCode: Integer);
        procedure FormActivate(Sender: TObject);
    private
    public
      { Public-Deklarationen }
    end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    
    procedure TForm1.ServerSocket1ClientError(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    begin
      Errorcode := 0;
    end;
    
    procedure TForm1.MyServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
    var
      rec: CustomRec;
      sInt, reply: string;
      iInt, errorPos: Integer;
    begin
      edit1.Text := Socket.ReceiveText;
    
      sInt := StringReplace(Trim(Edit1.Text), '''', '', [rfReplaceAll]);
      Val(sInt, iInt, errorPos);
    
      if errorPos = 0 then begin
        if iInt in [Low(Byte)..High(Byte)] then begin
          rec.Zahl := iInt;
          iInt := iInt +1;
          reply := IntToStr(rec.Zahl);
        end;
      end
      else
        reply := '-1';
        reply := 'reply ' + reply + ' accepted';
      Socket.SendText(reply + #13#10);
    end;
    
    procedure TForm1.ClientSocket1Error(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    begin
      Errorcode := 0;
    end;
    
    procedure TForm1.FormActivate(Sender: TObject);
    begin
      ClientSocket1 := TClientSocket.Create(Self);
      ClientSocket1.OnError := ClientSocket1Error;
    
      ServerSocket1 := TServerSocket.Create(Self);
      ServerSocket1.OnClientError := ServerSocket1ClientError;
      ServerSocket1.OnClientRead := MyServerSocket1ClientRead;
    
      ClientSocket1.Port := 10003;
      ClientSocket1.Host := '127.0.0.1';
    
      ServerSocket1.Port := 10003;
      ServerSocket1.Open;
    end;
    
    end.
    
    class TCPClient {
        private static int input;
    public static void main(String[] args) throws UnknownHostException, IOException {
    
        Socket echoSocket = new Socket("127.0.0.1", 10003);
        Timer timer = new Timer();
        input = 0;
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                try {
                    input = input +1;
                    doTime(echoSocket, input);
                } catch (IOException e) {
                    e.printStackTrace();
                }  
            }
        }, 1000,1000);   
    }
    
    private static void doTime(Socket echoSocket, int input) throws IOException {
        try {
            PrintWriter out = new PrintWriter(echoSocket.getOutputStream(), true);
            BufferedReader in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
            //the next 2 lines resume like: if you have to die, die fast
            int value = input;//ensure that input is an Integer
            assert (value >= 0 && value <= 255);// ensure that the Integer is in the Delphi's Byte range
            System.out.println("sending server reply number : " + value);
            out.println(value);
            System.out.println("server replies: " + in.readLine());
    
        } finally {
            //  echoSocket.close();
        }
    }