• Please review our updated Terms and Rules here

new FAST DOS VNC-like remote control server

Is this running on TCP? Offering a window size of one frame might sort it. Other options that might be worth exploring are back-pressure or sending ICMP source quench?

It's UDP only so far.

UDP is best effort. So on a local network using switches, it should be perfect - even when connecting 10 MB/sec hardware to gigabit hardware. But you will see more packet drops as you go through other people's routers and networks. When routers start backing up one of the first things they can do is jettison the UDP packets. It doesn't happen as often as it used to but it still does, and without a mechanism to detect lost packets only the end application can correct it.
 
Mike, your programming skills are quite something.

Really looking forward to trying this - just need an 8-bit NIC (and enough courage to leave a 27-year old PC running unattended... in my wooden workshop...!)

thanks, i'm trying my best to improve! not so long ago, anything other than BASIC scared me lawl. i still have much to learn. :p

btw you can pick up 8-bit NICs on ebay for $20 at pretty much any given time. i reccommend either a 3C503 or an EtherExpress 8/16. NE1000 cards work fine too, but the performance is awful compared to those other two models. (at least in my experience)



This is awesome. I intend to use this on my 486 machine to do DOS stuff.

that would be great! let me know if there are any problems, please!



Video: Beyond current scope of legacy ms-dos remote control app. Blank screen on client. Selected window and typed.

hmm, what do you mean exactly? the screen doesn't show at all? you mean in a certain graphics mode, or does it not show anything in 80x25 text mode either?
 
okay, here is the new version that doesn't actually work by scanning and comparing individual lines... the client just requests a full screen periodically:

http://rubbermallet.org/remoter-server.zip

http://rubbermallet.org/remoter-client.zip

^this should now work fine with 80x25 text mode, 320x200 4-color CGA, and 640x200 B&W CGA graphics.

the default update delay is 100 ms, but you can change it by putting -delay # on the command line after the IP address of the server. where, of course, # means value in milliseconds.
 
just wondering, has anybody tried this? and if so, any problems?

TCP mostly works in my stack now, btw. it sends and receives, but sometimes, some servers give me problems with their SEQ numbers after i ACK.. working on it.
 
just wondering, has anybody tried this? and if so, any problems?

same problems as lutiana here...

sdl_app window on client machine is just a black screen.
keypresses from client are reaching server.
server responds to ping with minitcp loaded.
have tried 2 machines as client with identical results (p4-xpsp2, p3-winme)
have tried 2 machines as server with identical results (8086-cga-dos622-wd8003, 8086-vga-dos622-3c503)
network is 10base2/10baseT all with static IP.
software installed in c:\remoter
 
I managed to make it work once with my PS/2. I ran remoter-client with a delay of 500ms and made sure to clear the screen before running remoter-client - and it worked! Since then, I've never been able to make remoter work again.

Oh, and I did manage to get ahold of a 10/100 ethernet switch, so that should make some difference.
 
Oh, and I did manage to get ahold of a 10/100 ethernet switch, so that should make some difference.

Reread my earlier post - the switch was not your problem. Switches auto-negotiate and buffer packets, so there is no chance for collisions. It just works.
 
Reread my earlier post - the switch was not your problem. Switches auto-negotiate and buffer packets, so there is no chance for collisions. It just works.
I've never had good luck with 10Mbps hardware and Gigabit, even more so when the Gigabit stuff is from Netgear.
 
just wondering, has anybody tried this? and if so, any problems?

further to my message yesterday i decided to dig a littler deeper..

when remoter client is started the sdl_app/Remoter Client window doesnt
update despite keyboard data from client being successfully received and
processed by the server.

looking at the properties of the client NIC it shows lots of outgoing
packets but none being received by windows while remoter client is running.

to investigate further i put a packet sniffer onto the lan and took a capture
while the remoter client was connecting.

server is 172.23.0.7 02608CDBF637
client is 172.23.0.25 00C0DFE131A8
Code:
 1) 19.102 002E DIX: Broadcast    <- 00C0DFE131A8 [0806] ARP: (0800) REQUEST from 172.23.0.25 for 172.23.0.7
 2) 19.103 002E DIX: 00C0DFE131A8 <- 02608CDBF637 [0806] ARP: (0800) REPLY from 172.23.0.7 to 172.23.0.25
 3) 19.104 002E DIX: 02608CDBF637 <- 00C0DFE131A8 [0800] IP: 172.23.0.25 -> 172.23.0.7 UDP: 1034->9001 DATA: E8 03
 4) 19.182 002E DIX: 02608CDBF637 <- 00C0DFE131A8 [0800] IP: 172.23.0.25 -> 172.23.0.7 UDP: 1034->9001 DATA: EB 03
 5) 19.201 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 00 00 0B 13 03 00 20 07 ...
 6) 19.218 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 78 05 0B 13 03 00 20 07 ...
 7) 19.235 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: F0 0A 0B 13 03 00 20 07 ...
 8) 19.293 002E DIX: 02608CDBF637 <- 00C0DFE131A8 [0800] IP: 172.23.0.25 -> 172.23.0.7 UDP: 1034->9001 DATA: EB 03
 9) 19.312 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 00 00 0B 13 03 00 20 07 ...
10) 19.329 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 78 05 0B 13 03 00 20 07 ...
11) 19.346 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: F0 0A 0B 13 03 00 20 07 ...
12) 19.400 002E DIX: 02608CDBF637 <- 00C0DFE131A8 [0800] IP: 172.23.0.25 -> 172.23.0.7 UDP: 1034->9001 DATA: EB 03
13) 19.419 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 00 00 0B 13 03 00 20 07 ...
14) 19.436 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 78 05 0B 13 03 00 20 07 ...
15) 19.453 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: F0 0A 0B 13 03 00 20 07 ...

from the capture i can see the screen IS being sent by server, packet 5/6/7,
packet 9/10/11 etc, however the client is not processing these packets.

could this be because they are being sent as ip within an ethernet broadcast
packet rather than specifically to the remoter client's ethernet address?
 
further to my message yesterday i decided to dig a littler deeper..

when remoter client is started the sdl_app/Remoter Client window doesnt
update despite keyboard data from client being successfully received and
processed by the server.

looking at the properties of the client NIC it shows lots of outgoing
packets but none being received by windows while remoter client is running.

to investigate further i put a packet sniffer onto the lan and took a capture
while the remoter client was connecting.

server is 172.23.0.7 02608CDBF637
client is 172.23.0.25 00C0DFE131A8
Code:
 1) 19.102 002E DIX: Broadcast    <- 00C0DFE131A8 [0806] ARP: (0800) REQUEST from 172.23.0.25 for 172.23.0.7
 2) 19.103 002E DIX: 00C0DFE131A8 <- 02608CDBF637 [0806] ARP: (0800) REPLY from 172.23.0.7 to 172.23.0.25
 3) 19.104 002E DIX: 02608CDBF637 <- 00C0DFE131A8 [0800] IP: 172.23.0.25 -> 172.23.0.7 UDP: 1034->9001 DATA: E8 03
 4) 19.182 002E DIX: 02608CDBF637 <- 00C0DFE131A8 [0800] IP: 172.23.0.25 -> 172.23.0.7 UDP: 1034->9001 DATA: EB 03
 5) 19.201 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 00 00 0B 13 03 00 20 07 ...
 6) 19.218 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 78 05 0B 13 03 00 20 07 ...
 7) 19.235 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: F0 0A 0B 13 03 00 20 07 ...
 8) 19.293 002E DIX: 02608CDBF637 <- 00C0DFE131A8 [0800] IP: 172.23.0.25 -> 172.23.0.7 UDP: 1034->9001 DATA: EB 03
 9) 19.312 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 00 00 0B 13 03 00 20 07 ...
10) 19.329 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 78 05 0B 13 03 00 20 07 ...
11) 19.346 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: F0 0A 0B 13 03 00 20 07 ...
12) 19.400 002E DIX: 02608CDBF637 <- 00C0DFE131A8 [0800] IP: 172.23.0.25 -> 172.23.0.7 UDP: 1034->9001 DATA: EB 03
13) 19.419 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 00 00 0B 13 03 00 20 07 ...
14) 19.436 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: 78 05 0B 13 03 00 20 07 ...
15) 19.453 059A DIX: Broadcast    <- 02608CDBF637 [0800] IP: 172.23.0.7 -> 172.23.0.25 UDP: 9001->9002 DATA: F0 0A 0B 13 03 00 20 07 ...

from the capture i can see the screen IS being sent by server, packet 5/6/7,
packet 9/10/11 etc, however the client is not processing these packets.

could this be because they are being sent as ip within an ethernet broadcast
packet rather than specifically to the remoter client's ethernet address?

thanks for playing around with it. i was going to post that it could be the issue. windows seems picky about it. it works on my machines, but some people have complained it doesn't on theirs. the old version of the IP stack i had bundled with the server always sent out the UDP packets to MAC FF:FF:FF:FF:FF:FF, but i've got that changed now. all the checksums match up to what they should be, and the packets arent otherwise malformed, so that must be it.

i'll up a new version a bit later on with the change. fwiw, i've got the TCP end mostly working too now even though this program won't use it. it seems to work fine other than it being flakey on the connection termination with the teardown routine (FIN+ACKs, etc) but i'm sure i will get it soon enough. i'm able to connect to web servers, telnet BBS servers, etc and exchange data okay.

this isn't remoter-related, but... using my stack to connect to some synchronet BBS server over TCP on an 8088 box - http://www.youtube.com/watch?v=rOGnisUzIjg
 
Last edited:
Hey Mike! Pretty cool!! Got it working on my 5155 as the host and the client on my Dell netbook with ATOM processor on Windows 7. Originally tried with XP but got no video on the client, but keystrokes went though to the host. Since the dell dual boots to win 7 or XP I tried Win 7 and it worked fine. But there are some delays in grafic modes. Are there any comand line options to tweak timings? ie delays
 
Hey Mike! Pretty cool!! Got it working on my 5155 as the host and the client on my Dell netbook with ATOM processor on Windows 7. Originally tried with XP but got no video on the client, but keystrokes went though to the host. Since the dell dual boots to win 7 or XP I tried Win 7 and it worked fine. But there are some delays in grafic modes. Are there any comand line options to tweak timings? ie delays

hi ibmapc, i'm glad somebody is getting some use out of this! the graphics modes will be a bit sluggish if the server is an 8088, since the screen is 16000 bytes but yes you can tinker with the delay timing. when invoking the client, use -delay # where # is how many milliseconds the clients waits between refresh requests. the default is 100 ms.

i usually do 200 ms when connecting to an 8088.
 
since there seem to be some people interested in this program, i decided to go ahead and release all the source code if anybody wants to do some more work with it. this zip file contains the code for my MiniTCP TSR TCP/IP stack, the Remoter server, client, and the SetIP utility that configures network parameters in MINITCP.COM.

the TCP stack and the Remoter server are both written entirely in 8086 assembly. SetIP is QuickBASIC, and the Remoter client is FreeBASIC for Windows. any questions, just ask and i'll help.

http://rubbermallet.org/remoter-source-code.zip

note that the TCP stack has what seems to be completely working UDP code, but the TCP stuff can be a little buggy. Remoter only uses the UDP functions. i stopped working on the stack in ASM and wrote a new one with working TCP but it's now a C library, not a TSR done in assembler.
 
i was thinking if anybody actually does some more work on this, it would help if i explained the protocol that is used. as mentioned before, it's UDP-based to keep the overhead minimal on 8088s. the protocol is extremely simple. the server listens on port UDP 9001. it sends data back to the client on port UDP 9002.

this is taken from the end of the server asm source. i added comments just now. this below is the packet format that the DOS machine running the server sends upon the client requesting a screen update.

Code:
pkt_vid_ptr dw 0 ;the offset inside the video memory segment where the 1400 data bytes in this packet begin at
pkt_cursor  dw 0 ;tells client where cursor is on screen, column is first byte, row second. filled in by DX result from int 10h, AH=3 on update requests
pkt_vidmode db 3 ;tells client current video mode
pkt_port3d9 db 0 ;video card status port's value
pktbuf      dw 1400 dup (0) ;actual data from video memory is here


below is the code that runs when the server receives an update request packet from the client, which fills in the packet data structure, including looping until all of the visible video memory data has been sent. there is a table elsewhere in the code that has the total visible video memory lengths for each BIOS video mode number, so it uses that to determine how much is sent.

Code:
  do_update:
    cld
    mov ax, 40h ;BIOS data area
    mov ds, ax
    mov bh, [62h] ;get active video page
    mov ah, 3
    int 10h
    mov cs:[pkt_cursor], dx
    
    mov dx, 3D9h
    in al, dx
    mov cs:[pkt_port3d9], al
    
    mov ah, 0Fh ;get video mode
    int 10h
    mov cs:[pkt_vidmode], al
    xor ah, ah    
    mov di, ax
    shl di, 1 ;table of visible video memory sizes is of 16-bit words, double video mode value for indexing into this table.
    mov bx, offset mode_size
    mov ax, cs:[bx+di]
    mov cs:[vid_mem_top], ax
    mov bx, offset mode_seg
    mov ax, cs:[bx+di]
    mov cs:[vid_mem_seg], ax

    mov cs:[vid_mem_ptr], 0
    
  update_loop:
    mov ax, cs:[vid_mem_ptr] ;get current position of video memory pointer
    cmp ax, cs:[vid_mem_top] ;compare it to the total size we need to send according to our current video mode
    ja update_done ;if limit is passed, we're done sending this screen update
    
    mov ax, cs:[vid_mem_seg] ;otherwise get segment of beginning of current mode's video memory (usually B800h)
    mov ds, ax ;shove it into DS
    mov ax, cs ;get our CS (because our packet data structure is in it)
    mov es, ax ;and shove it into ES
    mov si, cs:[vid_mem_ptr] ;set source index to current video memory offset pointer
    mov cs:[pkt_vid_ptr], si ;set it in our outgoing data packet
    mov di, offset pktbuf ;set destination index to data area of outgoing packet
    mov cx, 700 ;1400 bytes, so 700 words
    rep movsw ;copy it
    mov cs:[vid_mem_ptr], si ;update our current offset pointer based on new source index
    
    call send_pkt ;send it out!
    
    jmp update_loop ;do it all again
  
  update_done:



so, thats the format of the update packets the server sends to the client. as for the packets the client sends to the server, it's very simple. there are 4 different types of packets the server can send. they all contain only 2 bytes of data, except for the "new keypress" packet which is 3 bytes.

the first 2 bytes are a 16-bit word, possible values are: (these values are decimal, not hex)
1000 = "set IP" packet. it instructs the server to read the client's IP from the UDP header, save it, and only process future packets coming from it.

1001 = "clear IP" packet. the server nulls the previously saved client IP. the client sends it when it is closed.

1002 = "new keypress" packet. this packet has one more byte, which is simply the keyboard scancode of the key pressed. they are exactly the same as the scancodes the BIOS would read from the real keyboard controller on port 60h. in fact, there is assembly code in the server directly taken from the keyboard interrupt (int 9h) code in the generic XT BIOS available at phatcode.net. it's just modified to use the byte from the packet as if it were the keyboard controller, rather than reading it from port 60h.

1003 = "screen update/refresh request". the server immediately sends the data from visible video memory back to the client over several packets. (using the code shown above)

the set IP and clear IP stuff is not intended to be any sort of security or authentication. the only purpose of it is to keep the server from processing the incoming packet at all if it isn't from the client's IP. this is just to save CPU cycles on the server if some kind of random UDP packet gets received from somewhere. (just on the extremely off-chance that said random packet begins with a 16-bit value of 1002/1003. i guess this really is kind of pointless anyway, if the packet had a 1000 it would interpret it as "set IP" heh)

that's about it. feel free to make it more robust if you work on it, that certainly couldn't hurt. i came up with the whole thing pretty hastily, just eager to get something working properly. :)

one very useful/important thing that could be added is support for monochrome adapters. it currently only supports video memory for text modes beginning at segment B800h. the only other segment it knows of is A000h if the video mode is 13h. (MCGA 320x200, speaking of which it does not support transferring palette information yet so MCGA modes will almost certainly look screwed up)

the easy way of going about monochrome support would be to detect video type when the server is first started, and in the update_loop code always set the values of words vid_mem_top to 4000 bytes, and vid_mem_seg to B000h if it's a monochrome adapter.
 
Last edited:
Back
Top