TxT over UDP

Hello, I need to send several lines contained inside a TxT file, one at the time, over UDP. I am not very good at programming and would like someone to give me some advice. Thanks.

I currently do this manually every time I need to. It will be great if I can make it automatically.

Hello Luis,

You can achieve what you want with a simple script. Open the file, then iterate over its contents and transmit it line by line:

import "io_base.jncx"
import "io_MappedFile.jnc"

void main() {
	connect(); // ensure the transport is connected

	io.MappedFile file;
	file.open("file-path", io.FileOpenFlags.ReadOnly);
	char const* p = file.view(0, file.m_size);
	char const* end = p + file.m_size;
	
	while (p < end) {
		char const* nl = memchr(p, '\n', end - p);
		if (!nl) {
			if (p < end)
				transmit(p, end - p);
			break;
		}

		transmit(p, nl - p + 1); // include \n
		// transmit(p, nl - p);  // omit \n
		p = nl + 1;
	}
}

Thanks Vladimir!

I set the path to my txt file and run the script. I know it found the file but I get this error:

"Script transmit error:
The filename, directory name, or volume label syntax is incorrect."

File name syntax is in MS-DOS format. "file.open("C:\TMP\script\text.txt", io.FileOpenFlags.ReadOnly);"

Text file looks like this:

8308864495038423916F010201020000628C1DA7628C1DA705F37E4CCDD503B40000000000000000007410020004FFBF0F001Ea199030600000000000000106000000000001A35DF02C8026962347EF0
8308864495038423916F010201020001628C1DA7628C1DA705F37E4CCDD503B40000000000000000007411020004FFBF0F001Ea199030600000000000000106100000000001B333702C8026A62347EF0

...those are just two lines, the file has many more.

What could I have done wrong?

Literals in Jancy, just like in C, use escape-encoding with \ as the escape prefix. As such, the resulting path is incorrect.

You can either:

  • double-up the \ characters (i.e., "C:\\TMP\\script\\text.txt")
  • use the forward slash character / (i.e., "C:/TMP/script/text.txt")
  • use a raw literal that won't apply escape-encoding (i.e., r"C:\TMP\script\text.txt")

Hope this helps!

Hi, it worked perfectly. It was suppose to send the lines one by one, but it doesn't. I set a delay at the end of the "while" however is not the solution. How can I solve it?

Just tried it with some local text file and it worked as expected:

392ea4ab-d151-4145-9e8e-5dff2d6769d3-image.png

Could you please share some details about how exactly it doesn't work on your machine (a screenshot maybe)? Re delays -- delays might be necessary if the remote node isn't fast enough to process incoming UDP packets, but the script should send the file line by line regardless of the delays.

I made a mistake with the file I was using. Everything is fine with the script. Thank you very much. This has saved me a lot of work.

I am now very interested in how this script works. If you don't feel that I abuse your willingness, can you briefly explain how the script works? The operation of file.view is particularly confusing to me as I don't know whether the value of the pointer or the contents of the file is stored in "p".

The io.MappedFile (https://vovkos.github.io/jancy/stdlib/class_io_MappedFile.html) provides a convenient and efficient way of accessing files -- especially in read-only mode.

Instead of querying file size, then allocating a buffer, then reading the contents into this buffer -- theio.MappedFile.view method simply maps the requested region of the file and returns a pointer to the mapped region. Mapped files normally give more efficient access on both Windows and Unix (Linux/Mac). If the file is too big, you can sequentially call io.MappedFile.view for sub-regions of the file -- the management of mapped regions happens behind the scene.

In our case, we asked to view a region at file offset 0, file.m_size bytes long -- so the returned pointer can be used to access the whole file.

A more traditional approach would look like:

io.File file;
file.open(fileName, io.FileOpenFlags.ReadOnly);
void* p = new char[file.m_size];
file.read(p, file.m_size);

// work with p

Thanks Vladimir!