【发布时间】:2018-06-20 03:32:23
【问题描述】:
当我关闭与某些客户端的连接时会发生此错误。错误在服务器的这个代码行上:
Received := SocketStrm.Read(Data, SizeOf(Data));
而且,当智能手机重新启动时(或者,例如,当我关闭客户端应用程序时),丢失的客户端数据不会从服务器应用程序的ListView 中删除。
有人可以帮我解决这两个错误吗?
这是我如何发送数据的代码:
客户端(安卓):
public class MainActivity extends AppCompatActivity {
private Socket xclientSocket;
class ClientThread implements Runnable {
@Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName("192.168.15.12");
xclientSocket = new Socket(serverAddr, 101);
new Thread(new CMDThread()).start();
} catch (Exception e1) {
System.out.println(e1.toString());
}
}
}
class CMDThread implements Runnable {
@Override
public void run() {
try {
while(xclientSocket.isConnected()){
BufferedReader xreader = new BufferedReader(new InputStreamReader(xclientSocket.getInputStream()));
DataOutputStream dOut = new DataOutputStream(xclientSocket.getOutputStream());
String xline;
if (xreader.ready()) {
while ((xline = xreader.readLine()) != null) {
System.out.println(xline);
if (xline != null && !xline.trim().isEmpty()) {
if (xline.equalsIgnoreCase("info")) {
DataOutputStream dOut = new DataOutputStream(xclientSocket.getOutputStream());
dOut.writeChars("<|data|>" + myDeviceProduct.toUpperCase() + "<|>" + myDeviceModel + "<|>" + myVersion + "<|>" + SIM_OPNAME + "<|>" + SIM_NUMBER + "<<|");
dOut.flush();
}
if (xline.equalsIgnoreCase("disconnect-client")) {
break;
}
}
}
}
}
System.out.println("Shutting down Socket!!");
xclientSocket.close();
}
catch (Exception e1) {
System.out.println(e1.toString());
}
}
}
///////////////////////// USAGE /////////////////////////////
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
}
}
服务器(德尔福):
type
TCMDSock_Thread = class(TServerClientThread)
private
function ArrayToString(const a: array of Char): string;
procedure addClientToListView;
protected
procedure ClientExecute; override;
end;
var
FMain: TFMain;
Manufacturer, Model, OsVersion, SIMOpName, SIMNumber: string;
implementation
{$R *.dfm}
//==============================================================================================================
function TCMDSock_Thread.ArrayToString(const a: array of Char): string;
begin
if Length(a)>0 then
SetString(Result, PChar(@a[0]), Length(a))
else
Result := '';
end;
procedure TCMDSock_Thread.addClientToListView;
var
Item: TListItem;
begin
Item := FMain.ListView1.Items.Add;
Item.Caption := IntToStr(ClientSocket.Handle);
Item.SubItems.Add(ClientSocket.RemoteAddress);
Item.SubItems.Add(ClientSocket.RemoteHost);
Item.SubItems.Add(Manufacturer +' - '+Model+' - '+OsVersion);
Item.SubItems.Add(SIMOpName+' - '+SIMNumber);
Item.Data := ClientSocket.Data;
FMain.ServerStatus.Panels.Items[1].Text := 'Connected';
end;
procedure TCMDSock_Thread.ClientExecute;
var
Data: array [0 .. 1023] Of Char;
SocketStrm: TWinSocketStream;
ReceivedText: string;
Received: Integer;
begin
ClientSocket.SendText('info' + #13#10);
SocketStrm := TWinSocketStream.Create(ClientSocket, 5000);
try
while ClientSocket.Connected do
begin
if not SocketStrm.WaitForData(100) then
Continue;
FillChar(Data, SizeOf(Data), #0);
SocketStrm.Read(Data, SizeOf(Data));
repeat
try
Received := SocketStrm.Read(Data, SizeOf(Data));
except
Break;
end;
until Received = 0;
ReceivedText := ArrayToString(Data);
if Pos('<|data|>', RecText) > 0 then
begin
Delete(ReceivedText, 1, Pos('<|data|>', ReceivedText) + 7);
Manufacturer := Copy(ReceivedText, 1, Pos('<|>', ReceivedText) - 1);
Delete(ReceivedText, 1, Pos('<|>', ReceivedText) + 2);
Model := Copy(ReceivedText, 1, Pos('<|>', ReceivedText) - 1);
Delete(ReceivedText, 1, Pos('<|>', ReceivedText) + 2);
OsVersion := Copy(ReceivedText, 1, Pos('<|>', ReceivedText) - 1);
Delete(ReceivedText, 1, Pos('<|>', ReceivedText) + 2);
SIMOpName := Copy(ReceivedText, 1, Pos('<|>', ReceivedText) - 1);
Delete(ReceivedText, 1, Pos('<|>', ReceivedText) + 2);
SIMNumber := Copy(ReceivedText, 1, Pos('<<|', ReceivedText) - 1);
Synchronize(addClientToListView);
end;
end;
finally
SocketStrm.Free;
end;
end;
//================================================================================================================
procedure TFMain.ServerSocket1GetThread(Sender: TObject;
ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread);
begin
SocketThread := TCMDSock_Thread.Create(False, ClientSocket);
end;
procedure TFMain.Button2Click(Sender: TObject); // <= PopupMenu
var
Index: Integer;
begin
Index := ListView1.Selected.Index;
if Index = -1 then
Exit;
ServerSocket1.Socket.Connections[Index].SendText('disconnect-client' + #13#10);
ServerSocket1.Active := False;
end;
procedure TFMain.ServerSocket1ClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
var
Item: TListItem;
begin
Item := FMain.ListView1.FindCaption(0, IntToStr(Socket.Handle), False, True, False);
if Item <> nil then
Item.Delete;
FMain.StatusBar1.Panels.Items[1].Text := 'Desconnected';
end;
【问题讨论】:
-
这个话题已经在其他
TServerSocket。我留下第一个TServerSocket只是为了接收截图。 -
但在screenshot code 上也会发生与上述相同的错误,换句话说,当我尝试同时断开两个android 套接字时,服务器上
TWinSocketStream.Read()中的此错误有两个例外.
标签: android multithreading sockets delphi delphi-xe5