Write some pairs of point pass file programs with Delphi (1)
Thesis:
Delphi is powerful, with Delphi write software, can greatly reduce the development cycle of software. This article describes how to write some pairs of Points file programs with Delphi.
--------------------------------------------
Delphi is powerful, with Delphi write software, can greatly reduce the development cycle of software. With regard to the basic idea of point-to-note file, a server software, a client software, uses the same port, after the connection, the client sends a request to the server, including the file name, size, etc. of the file to be passed, if the server Accept, start the file. Of course, there are two modes, ASCII codes, and bin when file transmission, but generally BIN can be. Based on the above discussion, I originally used Delphi4 NMSTRM and NMSTRMSERV controls to be completed, but I have tested, the NMSTRM control can be used for smaller files, and it is very convenient, but if the file is large (1M). So we use the Delphi TSERVERSOCKET and TCLIENTSOCKET to write this program due to the limitations of the Ethernet package and the Delphisocket process mechanism (Delphi, when you send a large Stream with a socket, the acceptor will inspire multiple ONREAD events, Delphi She only guarantees the completeness of each data in multiple ONREAD events without collecting data and returns to the user. So don't think you have sent the paid file in a socket, another in the other, the RECV can be. You must collect data or define your own protocol.), So we use custom protocols. The specification method for defining the protocol is to use the Record End. Such as:
TMYFILEPROTOCOL = Record
SSENDTYPE = (ST_QUERY, ST_REFUSE, ST_DATA, ST_ABORT, ...);
Ilength: Integer;
BUFSEND: BUFFER;
END;
I have tried this method, but I have failed, and I always think that my method is correct, but the program has been compiled, it is estimated to have problems with Delphi :) So I use another way in the following example programs. There are two attributes of RECEIVETEXT and RECEIVEBUF in the Socket class. In an OnRead event, you can only use the two attributes, so we can use a full variable to save whether it is called Text or buf, that is, read a text, and then BUF, this simulates TMYFILEPROTOCOL.
Start the program:
Write a simplest, mainly used to explain the method.
Define protocol:
Const
MP_QUERY = '1';
MP_REFUSE = '2';
MP_ACCEPT = '3';
MP_NEXTWILLBEDATA = '4';
MP_DATA = '5';
MP_ABORT = '6';
MP_OVER = '7';
MP_CHAT = '8';
Protocol Profile:
First, MP_QUERY is sent by the Client, and the server accepts MP_ACCEPT or MP_FEFUESE;
Client Accept MP_ACCEPT Send MP_FILEPROPERTY, Server accepts MP_NEXTWILLBEDATA;
Client Accepts Send MP_NEXTWILLBEDATA, and Server receives MP_DATA;
Client Accepts MP_DATA, sending data, Server accepts data, and sends MP_NEXTWILLBEDATA;
Loop until the Client sends MP_OVER;
MP_CHAT STRING can be sent in the middle;
Server program:
Put the following controls: SaveDialog1, BtnStartServer,
SS, (TSERVERSOCKET)
BTNStart Server.onClick (Sender: TOBJECT);
Begin
SS.PORT: = 2000;
ss.open;
END;
SS.ONCLIENTREAD (SENDER: TOBJECT; SOCKET: TCUSTOMWINSOCKET);
VAR
STEMP: STRING;
BUFRECV: POINTER;
Irecvlength: integer;
Begin
IF breadText Then
Begin
STEMP: = Socket.ReceiveText;
Case Stemp [1] of
MP_QUERY: Begin
// Reject here
Savedialog1.FileName: = Copy (STEMP, 2, Length (STEMP));
if Savedialog1.execute THEN
Begin
Socket.sendtext (MP_ACCEPT);
FSRECV: = TFileStream.create (Savedialog1.FileName, Fmcreate);
end
Else socket.sendtext (MP_REFUSE 'Lish');
END;
MP_FILEPROPERTY: BEGIN
/ / To send STRTOINT (STEMP, 2, Length (STEMP)))
// Time progress display. . .
Socket.sendtext (MP_NEXTWILLBEDATA);
END;
MP_NEXTWILLBEDATA: Begin
Socket.sendtext (MP_DATA);
BreadText: = false;
END;
MP_END: BEGIN
FSRECV.FREE
BreadText: = true;
END;
MP_ABORT: Begin
FSRECV.FREE;
BreadText: = true;
END;
MP_CHAT: BEGIN
// chat msg
END;
End; {of case}
end
Else Begin
Try
GetMem (BUFRECV, 2000); // 2000 Must> ibytesend
Socket.ReceiveBuf (bufRecv ^, IRECVLength);
FSRECV.WRITEBUFFER (BUFRECV ^, IRECVLength);
Finally
FreeMem (BUFRECV, 2000);
End; {of try}
BreadText: = true;
Socket.sendtext (MP_NEXTWILLBEDATA);
END;
END;
Client program:
Put the following controls: edtipaddress, OpenDialog1, BtnConnect, btnsendfile,
CS. (tclientsocket)
BtnConnect.onclick (Sender: TOBJECT);
Begin
Cs.address: = edtipaddress.text;
CS.PORT: = 2000;
Cs.connect;
END;
Btnsendfile.onclick (Sender: TOBJECT); Begin
IF openDialog1.execute the
Begin
cs.socket.sendtext (MP_QUERY OPENDIALOG1.FILENAME); // FileSize ???