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