Synapse TFTP file transfer lazarus / 38-Networking and Web Programming ---------------------------------------------------------------------- Jake012345 · 2020-05-28 07:27 Hello! I found the TTFTP in synapse but I read about it and I realized it isn't good for me... So I changed to TFTP but it's harder how can I use It? Some Guide/tutorial anywhere? ---------------------------------------------------------------------- PascalDragon · 2020-05-28 07:58 The TFTP protocol (provided by the TTFTP class is indeed mainly intended for file transfers for boot protocols like PXE). To download files using FTP (provided by the TFTP class) you can take a look here to get you started (I didn't test it myself though). ---------------------------------------------------------------------- Jake012345 · 2020-05-28 09:24 I found 3 procedure: Quote.DataStream(Tstream); .DataWrite(Tstream); .DataRead(Tstream); how can I use them and send the streams? Or I can use the file commands? (storeFile,directFile,...) Maybe ftpPutFile and ftpGetFile ? ---------------------------------------------------------------------- rvk · 2020-05-28 10:44 Quote from: Jake012345 on May 28, 2020, 11:24:00 amMaybe ftpPutFile and ftpGetFile ? Yes. Did you look at the link PascalDragon provided? There is an example. For further examples you can download synapse40.zip from http://synapse.ararat.cz/doku.php/download In that zip there is a demo directory (in the source directory) which has many examples. One of them is TFTPClient. Look at that one. ---------------------------------------------------------------------- Jake012345 · 2020-05-28 11:17 Thats okay. I think It's working like a real online server and I can upload and download the files with client program. Am I right? But I want to write a program what can send directly the files for it's 'sibling' program. Like a messenger, torrent, and the others. Sure not complicated like them. Just simple. Most simple. What am I have to use and how? Every example what I fount had a lot of extra what I don't need, and it's confusing me.. ---------------------------------------------------------------------- rvk · 2020-05-28 11:57 Quote from: Jake012345 on May 28, 2020, 01:17:37 pmI think It's working like a real online server and I can upload and download the files with client program. Am I right?Yes, you'll need an FTP server. But in the demo directory of Synapse there is also a TFTPServer example. So you could add a FTPserver on both ends to do the filetransfer up and down (of if you only need it one way it's even easier). Otherwise... you could use the TCP example from a few weeks ago. That was for sending and receiving text-messages. But you could implement something like: if you receive @file:filename:size as text... the following data (until size bytes) is binary information for a file. After that you'll need to ignore the received data as text until you receive the complete size-bytes of the file. or If mixing text and binary data is too hard you could also do something like If you receive @file:filename:port... you connect the client to the port of the other side and all data received on that is for file with filename. There is no standard for this. You'll need to implement it yourself. But using a small ftp server and client is so much easier. It's all implemented in one class (TTFTPSend), both server and client. http://synapse.ararat.cz/doc/help/ftptsend.TTFTPSend.html See the TFTCPClient and TFTPServer for an example. ---------------------------------------------------------------------- fred · 2020-05-28 12:00 Fot sending a file to a FTP server this is something I used years ago: Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses ftpsend; procedure SendToFTP;var FTP: TFTPSend; ok: boolean;begin ok := False; FTP := TFTPSend.Create; try try FTP.TargetHost := 'ftp.test.com'; FTP.UserName := 'test'; FTP.Password := 'test'; if FTP.Login then begin FTP.BinaryMode := true; FTP.DirectFile := true; FTP.DirectFileName := 'c:\test.zip'; if FTP.StoreFile('test.zip', false) then ok := True; FTP.Logout; end; if not ok then Log(FTP.ResultString); except on E: Exception do begin Log('Exception: '+E.Message); end; end; finally FTP.Free;end; I changed the original code to I hope I didn't change too much... ---------------------------------------------------------------------- Jake012345 · 2020-05-28 16:18 Can I read and write the stream with ftpsend and send it with blocksock? ---------------------------------------------------------------------- rvk · 2020-05-28 16:36 Quote from: Jake012345 on May 28, 2020, 06:18:16 pmCan I read and write the stream with ftpsend and send it with blocksock? No, why? You can use the the sendfile and recvfile for that. You could stuff some data with blocksock on the wire but that will only mess things up. Why would you want that? ---------------------------------------------------------------------- Jake012345 · 2020-05-28 16:41 There is sendfile command? ---------------------------------------------------------------------- rvk · 2020-05-28 16:51 Quote from: Jake012345 on May 28, 2020, 06:41:56 pmThere is sendfile command? Didn't you look at the link I gave for TFTPSend??? ---------------------------------------------------------------------- Jake012345 · 2020-05-29 04:42 Oh really but it's TFTP and that's UDP ---------------------------------------------------------------------- TRon · 2020-05-29 06:28 Quote from: Jake012345 on May 29, 2020, 06:42:20 amOh really but it's TFTP and that's UDP I let the code speak fro itself Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i constructor TFTPSend.Create;begin inherited Create; FFullResult := TStringList.Create; FDataStream := TMemoryStream.Create; FSock := TTCPBlockSocket.Create; {$LOOK a TCPBlockSocket} FSock.Owner := self; FSock.ConvertLineEnd := True; FDSock := TTCPBlockSocket.Create; {$LOOK a TCPBlockSocket} FDSock.Owner := self; FFtpList := TFTPList.Create; FTimeout := 300000; FTargetPort := cFtpProtocol; FUsername := 'anonymous'; FPassword := 'anonymous@' + FSock.LocalName; FDirectFile := False; FPassiveMode := True; FForceDefaultPort := False; FForceOldPort := false; FAccount := ''; FFWHost := ''; FFWPort := cFtpProtocol; FFWUsername := ''; FFWPassword := ''; FFWMode := 0; FBinaryMode := True; FAutoTLS := False; FFullSSL := False; FIsTLS := False; FIsDataTLS := False; FTLSonData := True;end; class TTFTPSend <> class TFTPSend But that doesn't seem to matter anyhows, as your end-goal seems something completely different then as stated here in this thread. Quote from: Jake012345 on May 28, 2020, 01:17:37 pmBut I want to write a program what can send directly the files for it's 'sibling' program. Like a messenger, torrent, and the others. Sure not complicated like them. Just simple. Most simple. What am I have to use and how? Every example what I fount had a lot of extra what I don't need, and it's confusing me.. All what you call extra is required to get a healthy synced communication going between server and client (*) (as was explained in an earlier thread, to which you did not reply and the advise was ignored so that you started yet another thread on the same subject, doing so repeatedly). (*) how _you_ wish to implement that (communication) is _your_ business. You would have to invent that for your custom purpose, and for that you need to have a clear picture of what you want with your client'/server model, and you can't simply play around with this topic gluing stand-alone examples together in the hopes that doing so will somehow work for your situation. In case there is a language barrier then please write things down in your native tongue, and post that together with the google translation. Right now it is starting to look like you are bashing your head against the proverbial wall over and over again. ---------------------------------------------------------------------- Jake012345 · 2020-05-29 07:27 Szeretnék írni egy programot ami szöveges üzeneteket és file-okat is képes küldeni, a program másik példányának. És lehetőleg a host képes legyen több klienst is kiszolgálni. Nem igazán érdekel hogy ez milyen kapcsolattal jön létre, de a nagyobb fájlok küldéséhet szükséges a TCP kapcsolat. I would like to write a program that can send text messages and files to another copy of the program. And preferably the host should be able to serve multiple clients. I don't really care what kind of connection this creates, but larger files may require a TCP connection. ---------------------------------------------------------------------- TRon · 2020-05-29 08:03 @Jake012345 There you go (and thank you), that is much more precise and better to understand for the reader QuoteI would like to write a program that can send text messages and files to another copy of the program. You wish to use _different_ methods of sending data. Quote And preferably the host should be able to serve multiple clients. You wish to a) supply multiple sockets (clients) all at once and/or b) one socket (client) after the other. Depending on what you want things can get complicated because option a would require to implement threads while option b could do without using threads. Quote I don't really care what kind of connection this creates, but larger files may require a TCP connection. The examples used in the earlier threads assumed TCPBlockSocket connections (TCP). But as written in the other thread: it is perfectly ok to switch from sending strings to sending raw data (read: streams) and back again, over the same socket but_ you_ would have to come up with a communication protocol. I even provided an example on how such communication protocol (in theory) _could_ look like. That is why there exists ready made (communication) protocols such as FTP, TFTP, HTML HTTP etc. These protocols where once made up and the RFC's determine how these clients and servers need to "talk" (communicate) to each other. That "talking" between client and servers is also known as (communication)-protocol. You would have to invent your own communication protocol in order to make things work exactly the way how you want it to work, just as any other existing protocols (FTP/TFPT/HTMLHTTP/etc) do. There is not an example in the world that is able to teach that for you. You can always have a look at already existing protocols (RFC's/code) and read how they implemented their communications, but i doubt they would be helpful for your specific situation (as you stated earlier that the extra's in the code seem to confuse you). edit: corrected html to read http, i was thinking http but wrote html ---------------------------------------------------------------------- PascalDragon · 2020-05-29 08:24 Quote from: TRon on May 29, 2020, 10:03:00 amThat is why there exists ready made (communication) protocols such as FTP, TFTP, HTML etc. These protocols where once made up and the RFC's determine how these clients and servers need to "talk" (communicate) to each other. That "talking" between client and servers is also known as (communication)-protocol. You would have to invent your own communication protocol in order to make things work exactly the way how you want it to work, just as any other existing protocols (FTP/TFPT/HTML/etc) do. There is not an example in the world that is able to teach that for you. You can always have a look at already existing protocols (RFC's/code) and read how they implemented their communications, but i doubt they would be helpful for your specific situation (as you stated earlier that the extra's in the code seem to confuse you). I take it you mean HTTP, not HTML ---------------------------------------------------------------------- TRon · 2020-05-29 08:28 Quote from: PascalDragon on May 29, 2020, 10:24:52 amI take it you mean HTTP, not HTML drats Indeed, i meant http. I'll correct that in my post. Thanks for noticing ---------------------------------------------------------------------- Jake012345 · 2020-05-29 08:31 You think I can do it easier with Lnet? ---------------------------------------------------------------------- TRon · 2020-05-29 08:43 Quote from: Jake012345 on May 29, 2020, 10:31:21 amYou think I can do it easier with Lnet? I have no experience with either synapse or lnet (i just read their documentation/examples) so your mileage may vary. However, the same rules as explained in my previous post apply for whatever network-library you are going to use. There is no shortcut, in case you might be inclined to believe as such. There is some difference when it comes to implementation between using blocking vs non-blocking sockets. My advise would be to just pick one network library that you are (most) comfortable with using and stick by it for a while. In the end you really should use multiple of them, implementing the same stuff, to be able to see/understand their differences and.or if you favour one in particular. Seeing that there are multiple people who already posted examples using synapse (also for you) i would stick to synapse but that is just a personal observation. ---------------------------------------------------------------------- Jake012345 · 2020-05-29 08:45 Thats good but I'm stupid for networking and the synapse is very detailed and hard ---------------------------------------------------------------------- balazsszekely · 2020-05-29 09:36 @Jake012345 QuoteThats good but I'm stupid for networking and the synapse is very detailed and hardFirst of all you're not stupid, just a beginner which is perfectly fine, we all were in the same shoes once. What you fail to understand is that network programming is not a trivial task, I'm not saying it's particularly hard either, but it takes time to learn it. You have two choices: 1. Start slowly, learn how to program first 2. Use an already coded example and don't worry about the details ---------------------------------------------------------------------- TRon · 2020-05-29 10:00 Quote from: Jake012345 on May 29, 2020, 10:45:41 amThats good but I'm stupid for networking and the synapse is very detailed and hard You're not stupid at all, i just think you are trying to do too much to quickly and perhaps more or less expect(ed) a ready-to-go solution (which doesn't exist as it depends on how _you_ want your communication to work for you) The language barrier doesn't particularly help there either Let's resume (from the other threads as well): You are basically looking at - the following documentation: http://synapse.ararat.cz/doc/help/ - leading to the following class hierarchy: http://synapse.ararat.cz/doc/help/ClassHierarchy.html - to use one class in particular: TTCPBlockSocket (http://synapse.ararat.cz/doc/help/blcksock.TTCPBlockSocket.html) that particular class (and it's ancestory) have (at least) 4 methods that qualify for usage to address your 'problem': - SendString (http://synapse.ararat.cz/doc/help/blcksock.TBlockSocket. html#SendString) - RecvString (http://synapse.ararat.cz/doc/help/blcksock.TBlockSocket. html#RecvString) - RecvStreamRaw (http://synapse.ararat.cz/doc/help/blcksock.TBlockSock et.html#RecvStreamRaw) - SendStreamRAW (http://synapse.ararat.cz/doc/help/blcksock.TBlockSock et.html#SendStreamRaw) Most of those functions/methods are part of the ancestor of TTCPBlockSocket named TBlockSocket http://synapse.ararat.cz/doc/help/blcksock.TBlockSocket.html and thus are available (as well) for TTCPBlockSocket User GetMem already helped you out with your starting code (https://fo rum.lazarus.freepascal.org/index.php/topic,49853.msg363139.html#msg363 139), but you never folowed up on his efforts. I pointed to a question someone had about SendStream (and you are more than welcome to use that instead of SendStreamRaw or others) , to which the reply was use SendStreamRaw and it had a nice example. https://stackoverflow.com/questions/30778703/lazarus-freepascal- synapse-send-file-to-tcpblocksocket You would need to put that all together, and come up with an idea how the server and client should communicate with each other, e.g. invent your own words (strings) that can be send (sendstring) and received (recvstring) and be interpreted by the client and server and the code acting on what meaning you gave to those words. something like a (very crude and wrong because it was based on sending byte by byte -> use a stream instead) conversation that i posted here (https://forum.lazarus.freepascal.org/index.php/topic,49853.msg363000. html#msg363000) Quote(*) snippet of a imaginative communication between client and server 1) client: hello server, are you ready to accept a byte that belong to the file i am sending ? 2) server: uhm, lemme think about that.... uhm yeah, i think i am able to manage to accept a byte, which file was that again ? 3) client: allrighty then,let me pick up that byte and send it to you.... hold on there it comes, i need to retrieve it first. 4) server: oh dear, i have accepted a byte from this client, now where do i store it ? was it this buffer ? That one is full, i need to flush that buffer first. 5) client: did i already send all bytes of this file ? If so th inform the server that we did so (so it can wait for or start the next instruction/conversation) and if not then return to the top of this communication-protocol-list else continue doing something else. The best would be to have a (solid) starting position (code-wise) where you can send strings from client to server and back again. Then you can start implementing your (actual) "conversation"-protocol between client and server. As user GetMem already suggested, take small steps at a time. edit: and in case you wish to have a look at a (more or less complete) starting position with sending strings back and forth between client and server then you could perhaps have take a look at this example from user rvk: Quote from: rvk on October 19, 2017, 02:57:09 pmyou should be able to click the link to get to the correct post. ---------------------------------------------------------------------- Jake012345 · 2020-05-29 10:29 So... Server: Client: 1. Create and open socket Connect 2. listening..... Send Sting(can I start to send the file?) 3. show savedialog waiting..... 4. send string (ok I'm ready) send streams 5. recv and write streams to file send string (Ok I'm done) 6. recv string and close the file+ recv sring and show message (transfer successful) send string(ok I got it ) ---------------------------------------------------------------------- TRon · 2020-05-29 10:42 Quote from: Jake012345 on May 29, 2020, 12:29:36 pmSo... Something like that, yes indeed If you do implement it as you just wrote then i'm sure you are going to be confronted with some hurdles, but those can be taken one step at a time. For instance, i never expected/imagined/anticipated on a user interaction such as a save-dialog (which takes an undetermined amount of time). In case you get stuck on some part during the conversation then post the offending code, describing what conversation you expected/implemented and what /where it failed for you. Debugging such "conversations" can be daunting. Make sure to write out lot's of information during the conversation so that you are able to see where things get stuck (writing text to the console will do, but writing to a LCL memo is ok as well). Do not rely on your interpretation(s), let code speak for itself ---------------------------------------------------------------------- rvk · 2020-05-29 10:49 Quote from: Jake012345 on May 29, 2020, 12:29:36 pmSo... Do you have your messaging part (strings) working? Simplest is that you send this from one side. @PUT,filename.raw,1234,54354456 CR+LF 1234 would be filesize and 54354456 would be a checksum for the file. If the client receives this it will switch to a mode to put all the next received bytes into a file named filename.raw (or whatever is provided in the string). When 1234 bytes are received the client does the checksum to check if the file is correct. Another alternative would be that there is a separate socket opened on a different port to receive the file. In that case, communication of stringmessages could continue on the string-socket. I don't think you need to put strings on that separate socket. Just only the complete file. With tcp you don't need to ask if you can send or that the send is successful. You could do that on the string-socket afterwards. ---------------------------------------------------------------------- Jake012345 · 2020-05-29 11:00 You said Quotei never expected/imagined/anticipated on a user interaction such as a save-dialog (which takes an undetermined amount of time). But how can you set the download folder? automatically the Downloads, or pre set it before receive the file? ---------------------------------------------------------------------- rvk · 2020-05-29 11:05 Quote from: Jake012345 on May 29, 2020, 01:00:29 pmYou said Quotei never expected/imagined/anticipated on a user interaction such as a save-dialog (which takes an undetermined amount of time). But how can you set the download folder? automatically the Downloads, or pre set it before receive the file? I would just put the file in either Downloads or your own preset downloads folder for you app. You could add a button for "downloaded files" which opens the explorer directly in that folder. Do downloads get initiated from the client (pull a file) or from the other side (push a file)? Or both? ---------------------------------------------------------------------- TRon · 2020-05-29 11:08 @rvk If going for the first option from your post, what is the best/correct way to (keep) sync with synapse ? Despite having (what i thought to be) a pretty solid conversation I sometimes ran into the situation that during receiving (on server side) the client went out of sync on occasion (switching back from raw byte stream mode to string-mode). In that situation the server had a much smaller buffer than client had (for testing purpose). Once out of sync .... Are CanWite and CanRead helpful there when situated at the correct locations, or .. ? ---------------------------------------------------------------------- Jake012345 · 2020-05-29 11:11 Sorry I can't understand QuoteDo downloads get initiated from the client (pull a file) or from the other side (push a file)? Or both? You asked that the client send or receive files? ---------------------------------------------------------------------- TRon · 2020-05-29 11:16 Quote from: Jake012345 on May 29, 2020, 01:00:29 pmYou said Quotei never expected/imagined/anticipated on a user interaction such as a save-dialog (which takes an undetermined amount of time). But how can you set the download folder? automatically the Downloads, or pre set it before receive the file? In the test that i wrote i simply used the executable's directory. So i added ".copy" to the received filename, in order to circumvent overwriting But... if i look at your bigger picture (game, server, multiple clients) then i would not bother users with such details during game- startup or gameplay. Depending on what file is actually send i place it the correct directory and set the location for that directory beforehand. That way you can f.e. have multiple locations for multiple types of files, e.g. pictures go to one directory, audio to another,updates somewhere else. Users can interact with such setting either crude by a .ini file or before the game actually starts. But... you are free to do as you like, that is why we can't tell you how you implement things. It is completely your idea/invention ---------------------------------------------------------------------- Jake012345 · 2020-05-29 11:17 How big the buffer can be? ---------------------------------------------------------------------- TRon · 2020-05-29 11:24 Quote from: Jake012345 on May 29, 2020, 01:17:48 pmHow big the buffer can be? Can be anything you want it to be, as long as the computer running the code has enough memory But... although perhaps a little risky, you could use a (buffered) filestream to directly write to disk. ---------------------------------------------------------------------- Jake012345 · 2020-05-29 11:26 So if I have a NASA computer I can read my real computer's all datas in the puffer? ---------------------------------------------------------------------- rvk · 2020-05-29 11:29 Quote from: TRon on May 29, 2020, 01:08:38 pmIf going for the first option from your post, what is the best/correct way to (keep) sync with synapse ? ... Are CanWite and CanRead helpful there when situated at the correct locations, or .. ? A smaller buffer on client side wouldn't matter in case of tcp. The communication will wait until the buffer is processed. So mixing raw data and strings shouldn't matter if everything goes well. Of course, when there is packetloss it can become quite chaotic then In that case opening a second socket for raw file transfer would be the better option. On sending side opening the socket for listening and waiting for connection and on the receiving side connecting to that. After that the sending side can just stuff the complete file on the wire. On the receiving side it will end up in the file specified earlier by the string-socket communication (like the @PUT,filename,1234,5678). In that case the raw data socket is only used for the actual filedata transfer and stays 'clean'. And there is no raw data on the string- socket. Also, the string-socket can continue sending and receiving data during file transport. Further communications (like @CONFIRM,filename,1234,5678) from the receiving end that the file is received correctly etc is indeed up to the yet to be defined protocol. Edit: I would use 1kb local buffer and write that to a tfilestream. ---------------------------------------------------------------------- Jake012345 · 2020-05-29 11:48 And how works the buffer? evey package contains the size and name of the file? EDIT: And other question: How can I set an Integer/byte/Word interval? for examle a variable 'state' can be 1-4? ---------------------------------------------------------------------- rvk · 2020-05-29 12:00 Quote from: Jake012345 on May 29, 2020, 01:48:10 pmAnd how works the buffer?You read into the buffer, just like you would read into a string. Quoteevey package contains the size and name of the file? You haven't really defined what exactly you want. If you have a messaging system where you send strings back and forth, you can use special characters for special commands. This is also the case in irc clients (with /). In my example I used @. And PUT as a command to send a file. After the command you could specify a filename, a size and a checksum to make sure the file was send correctly. This of course, is all up to what you want. All message without @ in front are just messages. And when you receive a string with @ in front, you have a command which you need to handle different (and not display on screen). ---------------------------------------------------------------------- TRon · 2020-05-29 12:11 Quote from: Jake012345 on May 29, 2020, 01:48:10 pmAnd how works the buffer? evey package contains the size and name of the file? Again, you can implement it any which way you wish to. You make up the rules for your own protocol Personally, i would opt for something like suggested by user rvk (assuming client is sending/pushing to server, non linear order): Code: [Select]Server: RecvString... Client: SendString("SENDFILE Filename.txt 1234 $BADFACE); Server - detects command SENDFILE from client and "goes into" sendfile mode (receiving end) Server - sendfile mode extracts from the received string: filename.txt (filename) 1234 (filesize) and $BADFACE (checksum), make other necessary preparations and ... Server: SendString("SENDFILE ACK"); Server: RecvStreamRaw... (loop recv until buffer full, when buffer full then write/append to filestream, if filesize matches then stop loop and close filestream). At same time update checksum and check with checksum from client, act depending on outcome Client: RecvString, must match "SENDFILE ACK" then ... Client: SendStreamRaw (see example stackoverflow, do not close/free socket) Server: See also previous server actions, only when all ok then SendString(SENDFILE OK) else SendString("SENDFILE FAIL"); Client: RecvString ... wait for server to send back the ok signal that file was received in good health, else act on FAIL from server It is all up to you.... ---------------------------------------------------------------------- Jake012345 · 2020-05-29 12:16 I thought so too, but what is the checksum how can I make it? There is any command for that or I have to use external program? and QuoteEDIT: And other question: How can I set an Integer/byte/Word interval? for examle a variable 'state' can be 1-4? ---------------------------------------------------------------------- TRon · 2020-05-29 12:29 Quote from: Jake012345 on May 29, 2020, 02:16:46 pmI thought so too, but what is the checksum? hzm.. in case you have to ask that question, then it is probably best to not bother with it for now. A checksum is like a verification number to see if all bytes where received correctly. There are many different checksum implementations available, CRC being on of them. The client calculates the checksum on the client side, the server calculates the checksum on the server side. If the checksum from client and server are the same (they match) then you are more sure that all bytes where send correctly over from client to server. There are less and more precise checksum implementations, as a general rule: the more accurate the more time it takes to "calculate" the checksum. But as said, there are many implementations. and QuoteEDIT: And other question: How can I set an Integer/byte/Word interval? for examle a variable 'state' can be 1-4? Sorry, i seem currently too dumbfounded to actually understand what you are asking. You mean like a set-type ? https://freepascal.org/docs- html/ref/refsu16.html ---------------------------------------------------------------------- Jake012345 · 2020-05-29 12:40 Quoteorry, i seem currently too dumbfounded to actually understand what you are asking. You mean like a set-type ? https://freepascal.org/docs- html/ref/refsu16.html Yes. I want to make a procedure whit 'case' like this: Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Procedure ListeningForIncomingConnections(Server:TTCPBlockSocket; Connection:TTCPBlockSocket; State:word //>>0-4);begin case State of 0:begin if server listening shutdown it end; 1:begin if server run then accept all connections 2:begin -||- after 1 connection close the server end;..... end; But I don't want to give a chance to use this procedure with a state key that it can't understand. It's not too important but I'm curious. ---------------------------------------------------------------------- TRon · 2020-05-29 12:53 I think you mean something like this: Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type TState = (stOne, stTwo, stThree, stFour); Procedure ListeningForIncomingConnections(State: TState);begin case State of stOne: { do something }; stTwo: { do something }; stThree: { do something }; else { do something that did not match any of the above,e.g. stFour}; end;end; Only those four 'values' are allowed to assign to variable State (or any variable that is defined as type TState). ---------------------------------------------------------------------- Jake012345 · 2020-05-29 12:56 thanks! ---------------------------------------------------------------------- TRon · 2020-05-29 13:08 Quote from: Jake012345 on May 29, 2020, 02:16:46 pmI thought so too, but what is the checksum how can I make it? There is any command for that or I have to use external program? It's quite annoying that someone rewrite original questions for answer see: https://github.com/graemeg/freepascal/tree/master/pack ages/hash/examples ---------------------------------------------------------------------- Jake012345 · 2020-05-29 13:18 QuoteIt's quite annoying that someone rewrite original questions Got it! ---------------------------------------------------------------------- TRon · 2020-05-29 15:30 Thank you very much for your answer rvk Quote from: rvk on May 29, 2020, 01:29:30 pmQuote from: TRon on May 29, 2020, 01:08:38 pmIf going for the first option from your post, what is the best/correct way to (keep) sync with synapse ? ... Are CanWite and CanRead helpful there when situated at the correct locations, or .. ? A smaller buffer on client side wouldn't matter in case of tcp. The communication will wait until the buffer is processed. So mixing raw data and strings shouldn't matter if everything goes well. Of course, when there is packetloss it can become quite chaotic then To (further) clarify, my issue is with pushing from client to server where the server has the smaller buffer..... but you seem to suggest that, in case everything goes well, there shouldn't be a problem. That is reason for me to believe i do still have something erroneously code lurking around I was/am not certain about how synapse would approach such situation internally (I'll take a closer look to its implementation details later). QuoteIn that case opening a second socket for raw file transfer would be the better option. ... Dearly noted and thank you for the comprehensive explanation on that part. ---------------------------------------------------------------------- rvk · 2020-05-29 17:05 Quote from: TRon on May 29, 2020, 05:30:19 pmTo (further) clarify, my issue is with pushing from client to server where the server has the smaller buffer..... but you seem to suggest that, in case everything goes well, there shouldn't be a problem. That is reason for me to believe i do still have something erroneously code lurking around I was/am not certain about how synapse would approach such situation internally (I'll take a closer look to its implementation details later). Internal packets of ethernet are already about 1500 bytes. And that's not even the buffer of your program. So packets are send and the sender waits for the acknowledgment. If that doesn't come there is a resend or a timeout at the end of the sender. Packets are not easily lost with tcp. The only thing could be that the sender sometimes needs to wait before the receiver handles the packets. That's what the timeout are for. And because that's all done by the ethernet driver, you shouldn't have any problems if the sender buffer is smaller. But don't set the timeout at the sender too small. ---------------------------------------------------------------------- Jake012345 · 2020-05-30 05:06 Hello! How can I get the size of file? I tried the: Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var f:file; filesize:int64; assignfile(f,filename);Filesize:=FileUtil.FileSize(f {or filename});showmessage(filename+IntToStr(filesize)); But I can see -1 if I use the filename or 255 if I declared filesize as byte and 288 if I use Reset(f) before and 4 or 44 if I used SizeOf() istead FileSize() (The real size is: 265 MB (278 040 455 byte) ) what is the good code? ---------------------------------------------------------------------- GAN · 2020-05-30 05:48 Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i var f:file of byte; filesize:int64; assign(f,filename);Reset(f);Filesize:=FileSize(f {or filename});Close(f);showmessage(filename+IntToStr(filesize)); See https://www.freepascal.org/docs-html/rtl/system/filesize.html ---------------------------------------------------------------------- Jake012345 · 2020-05-30 06:09 I have some more error... ---------------------------------------------------------------------- rvk · 2020-05-30 06:23 Quote from: Jake012345 on May 30, 2020, 08:09:46 amI have some more error... Use assignfile and closefile. Of better yet... just use Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses FileUtil;//...Filesize := FileUtil.FileSize(filename); ---------------------------------------------------------------------- Jake012345 · 2020-05-30 06:28 I have RunError(2) on Reset(f); ---------------------------------------------------------------------- rvk · 2020-05-30 06:30 Quote from: Jake012345 on May 30, 2020, 08:28:20 amI have RunError(2) on Reset(f); Don't use reset, assignfile and closefile. All you need is Filesize := FileUtil.FileSize(filename); Nothing else. Btw, runtime error 2 is file not found. So make sure the file exists. ---------------------------------------------------------------------- Jake012345 · 2020-05-30 06:34 Thanks! the runerror 2 was because I used the file name without path... ---------------------------------------------------------------------- Jake012345 · 2020-05-30 06:49 And what commands can I use to write and read stream from a file? Read/write or Read byte/Write byte or buffer,ansi string,word? or enough if I use similar in each parts? ---------------------------------------------------------------------- rvk · 2020-05-30 06:51 Use TFileStream. Examples can be found here https://wiki.freepascal.org/TFileStream ---------------------------------------------------------------------- Jake012345 · 2020-05-30 07:34 I can't understand this ---------------------------------------------------------------------- Jake012345 · 2020-05-30 07:39 how can I test if stream at the end? ---------------------------------------------------------------------- rvk · 2020-05-30 07:48 Quote from: Jake012345 on May 30, 2020, 09:34:26 amI can't understand this What part don't you understand? Try to understand it line by line. Quote from: Jake012345 on May 30, 2020, 09:39:34 amhow can I test if stream at the end? You check stream.position against stream.size. Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i while stream.position < stream.size dobegin // read from streamend; ---------------------------------------------------------------------- Jake012345 · 2020-05-30 07:51 I wrote this: Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i if mode='fileaccept' then begin FolderPath.Enabled:=false; MainStream.Create(infile_name,fmCreate); repeat if Connection.PeekByte(10)>0 then begin Connection.RecvStreamRaw(MainStream,10); MainStream.Position:=0; MainStream.Write(streambuffer[1],n); end; until IntToStr(FileUtil.FileSize(infile_name))=infile_size; MainStream.free; and this: Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i MainStream.Create(OpenFileDialog.FileName,fmOpenRead); repeat streambuffer:=''; MainStream.Read(streambuffer,MainStream.Size); Connection.SendStreamRaw(MainStream); until MainStream.; ---------------------------------------------------------------------- rvk · 2020-05-30 08:04 QuoteMainStream.Read(streambuffer,MainStream.Size);You read in the complete MainStream.Size here into the Streambuffer. So there is no need for a loop because you read the entire stream in one go. Do note that you'r buffer needs to be big enough for the complete file. But you have a string as buffer. My first question is... what kind of files are you transfering. If they are binary you'll need to use an array of bytes as buffer, not a string type. If they are binary, you can forget about buffers and just do a Connection.SendStreamRaw(Stream); and Connection.RecvStreamRaw(Stream); without any loop. Using the SendStreamRaw and RecvStreamRaw, Synapse will internally take care of everything. Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i MainStream. Create(infile_name,fmCreate);Connection.RecvStreamRaw(MainStream, 60000); // 60 seconds timeoutMainStream.Free; Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i MainStream. Create(OpenFileDialog.FileName,fmOpenRead);Connection.SendStreamRaw(Ma inStream);MainStream.Free; ---------------------------------------------------------------------- Jake012345 · 2020-05-30 08:09 But if my file is bigger than few GB? ---------------------------------------------------------------------- rvk · 2020-05-30 08:14 Quote from: Jake012345 on May 30, 2020, 10:09:47 amBut if my file is bigger than few GB? Not a problem. Internally Synapse will take care of everything. Including a buffer for sending and receiving. Only thing is you don't know the progress. But that's something for later. ---------------------------------------------------------------------- Jake012345 · 2020-05-30 08:16 but I can't send the whole file at once. I have to send it in parts. not? repeat read and send until done repeat recv and write until done ---------------------------------------------------------------------- rvk · 2020-05-30 08:18 Quote from: Jake012345 on May 30, 2020, 10:16:59 ambut I can't send the whole file at once. I have to send it in parts. not? NO. SendStreamRaw does all that for you. You only need the one call. No need for a loop because that's done internally by Synapse. ---------------------------------------------------------------------- Jake012345 · 2020-05-30 08:22 woah...!!! Coooool!!! ---------------------------------------------------------------------- Jake012345 · 2020-05-30 08:23 So with that I can send 9999 TB without 1TB RAM ? ---------------------------------------------------------------------- rvk · 2020-05-30 08:26 Quote from: Jake012345 on May 30, 2020, 10:23:25 amSo with that I can send 9999 TB without 1TB RAM ? Yes. Because of the internal loop inside Synapse. Do note... You done have a transfer-progress bar so you don't see how far rise 9999TB are. You could only see an indication when reading out MainStream.Position. But a progressbar is something for later on I guess. ---------------------------------------------------------------------- Jake012345 · 2020-05-30 08:27 But I can do the progressbar with stream.position? ---------------------------------------------------------------------- rvk · 2020-05-30 08:32 Quote from: Jake012345 on May 30, 2020, 10:27:49 amBut I can do the progressbar with stream.position? On the sender side, yes. Because you know the size there. And if you work with threads. Not sure about ttimer. On the receiving end you don't know the size (unless you transferred that via the string-socket). ---------------------------------------------------------------------- Jake012345 · 2020-05-30 08:35 I have problem... ---------------------------------------------------------------------- rvk · 2020-05-30 08:37 Quote from: Jake012345 on May 30, 2020, 10:35:40 amI have problem... How did you create the stream? Seems like you didn't create the stream and then you get a sigsegv error when reading from a nil pointer. ---------------------------------------------------------------------- Jake012345 · 2020-05-30 08:41 Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, strutils, FileUtil, laz_synapse, blcksock; type { TForm1 } TForm1 = class(TForm) ChecksumEdit: TEdit; FolderPath: TEdit; FolderLocateButton: TButton; FilePath: TEdit; FileLocateButton: TButton; FileSendButton: TButton; ConnectButton: TButton; Log: TMemo; OpenFileDialog: TOpenDialog; PortEdit: TEdit; IpEdit: TEdit; HostButton: TButton; OpenFolderDialog: TSelectDirectoryDialog; RadioButton1: TRadioButton; RadioButton2: TRadioButton; GetTimer: TTimer; procedure ConnectButtonClick(Sender: TObject); procedure ChecksumEditChange(Sender: TObject); procedure FileLocateButtonClick(Sender: TObject); procedure FileSendButtonClick(Sender: TObject); procedure FolderLocateButtonClick(Sender: TObject); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormCreate(Sender: TObject); procedure HostButtonClick(Sender: TObject); procedure RadioButton1Change(Sender: TObject); procedure RadioButton2Change(Sender: TObject); procedure GetTimerTimer(Sender: TObject); private public end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } var MainServer:TTCPBlockSocket; Connection:TTCPBlockSocket; AcceptState:byte=1; LogMessage:string; connected:boolean; filename:string; mode:string; checksum:string; MainStream:TFileStream; filesize:integer; streambuffer:string; procedure Logging;begin Form1.Log.Lines.Add(LogMessage); LogMessage:='';end; procedure TForm1.FolderLocateButtonClick(Sender: TObject);begin if OpenFolderDialog.execute then FolderPath.Text:=OpenFolderDialog.FileName; SetCurrentDir(OpenFolderDialog.FileName);end; procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);begin Halt;end; procedure TForm1.FormCreate(Sender: TObject);begin mode:='string';end; procedure TForm1.FileLocateButtonClick(Sender: TObject); var f:file; s:string;begin if OpenFileDialog.execute then FilePath.Text:=OpenFileDialog.FileName; filename:=ExtractDelimited(Wo rdCount(OpenFileDialog.FileName,[DirectorySeparator]), OpenFileDialog.FileName,[DirectorySeparator]); Filesize:=FileUtil.FileSize(OpenFileDialog.FileName); showmessage(filename+' '+IntToStr(filesize));end; procedure TForm1.FileSendButtonClick(Sender: TObject);begin mode:='filesend'; FilePath.Enabled:=false; if connected=true then if Connection.CanWrite(10) then if checksum<>'' then Connection.Sen dString('>StartSendFile'+':'+filename+':'+IntToStr(filesize) +':'+checksum+#13#10) else Connection.SendString('>StartSendFile '+':'+filename+':'+IntToStr(filesize)+#13#10); MainStream.Create(OpenFileDialog.FileName,fmOpenRead); Connection.SendStreamRaw(MainStream); MainStream.Free; mode:='string';end; procedure TForm1.ConnectButtonClick(Sender: TObject);begin connection:=TTCPBlockSocket.Create; Connection.CreateSocket; Connection.Connect(IpEdit.Text,PortEdit.Text); if Connection.LastError=0 then begin LogMessage:=('Successfully connected to ('+Connection.GetRemoteSinIP+')'); connected:=true; end; Logging;end; procedure TForm1.ChecksumEditChange(Sender: TObject);begin checksum:=ChecksumEdit.Text;end; procedure TForm1.HostButtonClick(Sender: TObject);begin MainServer:=TTCPBlockSocket.Create; MainServer.CreateSocket; MainServer.Bind(IpEdit.Text,PortEdit.Text); MainServer.Listen; LogMessage:='Server Run.'; Logging; repeat case AcceptState of 0: begin Exit; end; 1: begin Application.ProcessMessages; if MainServer.CanRead(100) then begin Connection:=TTCPBlockSocket.Create; Connection.CreateSocket; Connection.Socket:=MainServer.Accept; LogMessage:=('Connection accepted from ('+Connection.GetRemoteSinIP+')'); if LogMessage<>'' then Logging; connected:=true; end; end; end; until false;end; procedure TForm1.RadioButton1Change(Sender: TObject);begin if RadioButton1.Checked=true then AcceptState:=1;end; procedure TForm1.RadioButton2Change(Sender: TObject);begin if RadioButton1.Checked=true then AcceptState:=0;end; procedure TForm1.GetTimerTimer(Sender: TObject); var messagein:String; infile_name:string; infile_size:string; infile_checksum:string; f:file; n:integer;begin //TEXT MODE if connected then begin if mode='string' then begin messagein:=Connection.RecvString(10); if (messagein<>'') and (messagein[1]<>'>') then begin LogMessage:=messagein; Logging; end else if (messagein<>'') and (messagein[1]='>') then begin mode:='fileaccept'; infile_name:=ExtractDelimited(2,messagein,[':']); infile_size:=ExtractDelimited(3,messagein,[':']); infile_checksum:=ExtractDelimited(4,messagein,[':']); LogMessage:='Accepting file: '+infile_name+' Size: '+ infile_size+' Checksum: '+infile_checksum; logging; end; end; //FILE MODE if mode='fileaccept' then begin FolderPath.Enabled:=false; MainStream.Create(infile_name,fmCreate); Connection.RecvStreamRaw(MainStream, 10); MainStream.Free; mode:='string'; end; end;end; end. ---------------------------------------------------------------------- rvk · 2020-05-30 08:45 This line is incorrect. MainStream.Create(OpenFileDialog.FileName,fmOpenRead) Also for the reading stream. You don't assign anything to MainStream but called Create directly on the nil-pointer. It schould be something like MainStream := TFileStream.Create(... (Both for reading and writing stream) ---------------------------------------------------------------------- Jake012345 · 2020-05-30 08:47 ohh... really... ---------------------------------------------------------------------- Jake012345 · 2020-05-30 08:52 and the Unable to open file error? ---------------------------------------------------------------------- rvk · 2020-05-30 08:54 Quote from: Jake012345 on May 30, 2020, 10:52:34 amand the Unable to open file error? Code and exact error. ---------------------------------------------------------------------- Jake012345 · 2020-05-30 08:55 Code: Pascal [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, strutils, FileUtil, laz_synapse, blcksock; type { TForm1 } TForm1 = class(TForm) ChecksumEdit: TEdit; FolderPath: TEdit; FolderLocateButton: TButton; FilePath: TEdit; FileLocateButton: TButton; FileSendButton: TButton; ConnectButton: TButton; Log: TMemo; OpenFileDialog: TOpenDialog; PortEdit: TEdit; IpEdit: TEdit; HostButton: TButton; OpenFolderDialog: TSelectDirectoryDialog; RadioButton1: TRadioButton; RadioButton2: TRadioButton; GetTimer: TTimer; procedure ConnectButtonClick(Sender: TObject); procedure ChecksumEditChange(Sender: TObject); procedure FileLocateButtonClick(Sender: TObject); procedure FileSendButtonClick(Sender: TObject); procedure FolderLocateButtonClick(Sender: TObject); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); procedure FormCreate(Sender: TObject); procedure HostButtonClick(Sender: TObject); procedure RadioButton1Change(Sender: TObject); procedure RadioButton2Change(Sender: TObject); procedure GetTimerTimer(Sender: TObject); private public end; var Form1: TForm1; implementation {$R *.lfm} { TForm1 } var MainServer:TTCPBlockSocket; Connection:TTCPBlockSocket; AcceptState:byte=1; LogMessage:string; connected:boolean; filename:string; mode:string; checksum:string; MainStream:TFileStream; filesize:integer; streambuffer:string; procedure Logging;begin Form1.Log.Lines.Add(LogMessage); LogMessage:='';end; procedure TForm1.FolderLocateButtonClick(Sender: TObject);begin if OpenFolderDialog.execute then FolderPath.Text:=OpenFolderDialog.FileName; SetCurrentDir(OpenFolderDialog.FileName);end; procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);begin Halt;end; procedure TForm1.FormCreate(Sender: TObject);begin mode:='string';end; procedure TForm1.FileLocateButtonClick(Sender: TObject); var f:file; s:string;begin if OpenFileDialog.execute then FilePath.Text:=OpenFileDialog.FileName; filename:=ExtractDelimited(Wo rdCount(OpenFileDialog.FileName,[DirectorySeparator]), OpenFileDialog.FileName,[DirectorySeparator]); Filesize:=FileUtil.FileSize(OpenFileDialog.FileName); showmessage(filename+' '+IntToStr(filesize));end; procedure TForm1.FileSendButtonClick(Sender: TObject);begin mode:='filesend'; FilePath.Enabled:=false; if connected=true then if Connection.CanWrite(10) then if checksum<>'' then Connection.Sen dString('>StartSendFile'+':'+filename+':'+IntToStr(filesize) +':'+checksum+#13#10) else Connection.SendString('>StartSendFile '+':'+filename+':'+IntToStr(filesize)+#13#10); MainStream:=TFileStream.Create(OpenFileDialog.FileName,fmOpenRead); MainStream.Create(OpenFileDialog.FileName,fmOpenRead); Connection.SendStreamRaw(MainStream); MainStream.Free; mode:='string';end; procedure TForm1.ConnectButtonClick(Sender: TObject);begin connection:=TTCPBlockSocket.Create; Connection.CreateSocket; Connection.Connect(IpEdit.Text,PortEdit.Text); if Connection.LastError=0 then begin LogMessage:=('Successfully connected to ('+Connection.GetRemoteSinIP+')'); connected:=true; end; Logging;end; procedure TForm1.ChecksumEditChange(Sender: TObject);begin checksum:=ChecksumEdit.Text;end; procedure TForm1.HostButtonClick(Sender: TObject);begin MainServer:=TTCPBlockSocket.Create; MainServer.CreateSocket; MainServer.Bind(IpEdit.Text,PortEdit.Text); MainServer.Listen; LogMessage:='Server Run.'; Logging; repeat case AcceptState of 0: begin Exit; end; 1: begin Application.ProcessMessages; if MainServer.CanRead(100) then begin Connection:=TTCPBlockSocket.Create; Connection.CreateSocket; Connection.Socket:=MainServer.Accept; LogMessage:=('Connection accepted from ('+Connection.GetRemoteSinIP+')'); if LogMessage<>'' then Logging; connected:=true; end; end; end; until false;end; procedure TForm1.RadioButton1Change(Sender: TObject);begin if RadioButton1.Checked=true then AcceptState:=1;end; procedure TForm1.RadioButton2Change(Sender: TObject);begin if RadioButton1.Checked=true then AcceptState:=0;end; procedure TForm1.GetTimerTimer(Sender: TObject); var messagein:String; infile_name:string; infile_size:string; infile_checksum:string; f:file; n:integer;begin //TEXT MODE if connected then begin if mode='string' then begin messagein:=Connection.RecvString(10); if (messagein<>'') and (messagein[1]<>'>') then begin LogMessage:=messagein; Logging; end else if (messagein<>'') and (messagein[1]='>') then begin mode:='fileaccept'; infile_name:=ExtractDelimited(2,messagein,[':']); infile_size:=ExtractDelimited(3,messagein,[':']); infile_checksum:=ExtractDelimited(4,messagein,[':']); LogMessage:='Accepting file: '+infile_name+' Size: '+ infile_size+' Checksum: '+infile_checksum; logging; end; end; //FILE MODE if mode='fileaccept' then begin FolderPath.Enabled:=false; MainStream:=TFileStream.Create(infile_name,fmCreate); MainStream.Create(infile_name,fmCreate); Connection.RecvStreamRaw(MainStream, 10); MainStream.Free; mode:='string'; end; end;end; end. ---------------------------------------------------------------------- Jake012345 · 2020-05-30 08:55 But that's happening on txt files too. ---------------------------------------------------------------------- rvk · 2020-05-30 08:59 You still have the lines MainStream.Create(... On line 119 and 220. Remove them. You should never call Create directly on a variabele. Create should obly be called a classtype (for assigment). ---------------------------------------------------------------------- Jake012345 · 2020-05-30 09:01 I deleted the second creation lines and it's working! Thanks!! But why?: QuoteYou should never call Create directly on a variabele. Create should obly be called a classtype (for assigment). ---------------------------------------------------------------------- rvk · 2020-05-30 09:04 Quote from: Jake012345 on May 30, 2020, 11:01:45 amBut why?: QuoteYou should never call Create directly on a variabele. Create should obly be called a classtype (for assigment). Beause Create is a constructor. When creating an object, you call a Constructor method of the class, not the object: objectName := ClassName.Create(parms); Also see http://www.delphibasics.co.uk/RTL.asp?Name=Constructor Btw. It's the same for connection:=TTCPBlockSocket.Create Which you did properly ---------------------------------------------------------------------- Jake012345 · 2020-05-30 09:29 I started a transfer ... with 5GB VBox .vdi file... and somehow I got this code on log: Code: C [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Successfully connected to (127.0.0.1)Accepting file: windows32.vdi Size: 1075838976 Checksum: 998868565767A disk read error occurredNTLDR is missingNTLDR is compressedPress Ctrl+Alt+Del to restart