ZKTeco terminal not connecting to the PC, and the five checks that find why
The terminal is rarely the fault. The laptop usually is, and the way it fails looks like something else, so the order you check things in decides whether you fix it or change a setting that was already right.
In this piece
- ZKTeco default IP address, port and Comm Key
- A static IP on Windows 11, and why the gateway stays blank
- The five checks, in order
- The trap at step two: an unplugged cable looks like a missing IP
- The other trap: a Wi-Fi on the same numbers
- A ping on Windows can succeed at failing
- A check on a timer has to finish inside its interval
- The first laptop that was not ours
- What we have not confirmed
We built an offline attendance program for a university department in Nigeria. It talks to a ZKTeco K40 fingerprint terminal over one Ethernet cable, with no router, no Wi-Fi and no internet, and it replaces the terminal maker’s own software, ZKBio Time.Net.
When a ZKTeco device will not connect to the PC, the cause is usually on the PC’s side. This is the order we check things in, why that order, and what each failure looks like on Windows. Everything here was measured on one K40 (firmware Ver 6.60, September 2019) and Windows 11.
ZKTeco default IP address, port and Comm Key
| Setting | This PC | The terminal |
|---|---|---|
| IP address | 192.168.1.100 | 192.168.1.201 |
| Subnet mask | 255.255.255.0 | 255.255.255.0 |
| Default gateway | Blank | Not used |
| Port | 4370 | |
| Comm Key | 0 |
The terminal’s address and port are ZKTeco’s defaults, the ones its quick start guides print. On a K40 you can read them off the terminal itself: Menu > COMM. > Ethernet for the address, and Menu > COMM. > PC Connection for the port and the Comm Key. Read them there rather than trusting a default, because anyone with the keypad can change them.
The PC’s address can be anything on 192.168.1.x except the terminal’s own. We use .100.
A static IP on Windows 11, and why the gateway stays blank
A gateway is where a computer sends traffic meant for other networks. A cable to one terminal leads nowhere else, so there is nothing to put in the box.
Leaving it blank also steps round the one Windows 11 behaviour that stops people
at this point. The Settings app will not save a manual IPv4 address that has a
gateway and no DNS server; it says it cannot save the settings
(The Windows Club,
ETC support).
People fill in a gateway because the form has a box for one, then get stuck on a
DNS server they do not have. Clear the gateway and it saves. The older adapter
window, opened with ncpa.cpl, is less strict about this.
The five checks, in order
Each step can only fail for its own reason if the step before it passed. Checked out of order, a loose cable reads as a wrong setting, and people go and change a setting that was right.
- Is there a cable, and is the link up? Windows reports this per adapter:
Get-NetAdapter -Physicalsays Up or Disconnected. A laptop with no Ethernet port needs a USB adapter. - Is this PC on the terminal’s network? The Ethernet adapter itself has to hold an address on 192.168.1.0/24. An address on the Wi-Fi does not count.
- Will traffic to the terminal leave through the cable? Ask the operating
system which local address it would use to reach 192.168.1.201. A UDP
connect()answers that without sending a packet. If it names the Wi-Fi’s address, the cable is not the route. - Does the terminal answer a ping?
- Does port 4370 accept a connection?
Our program runs all five and gives one plain sentence for each. What each failure usually means:
| Stops at | What it usually is | What to do |
|---|---|---|
| 1. Cable | The cable is out at one end, or the terminal is off | Push it in firmly at both ends. Ours came out twice during the build |
| 2. Address | The adapter is still set to get an address automatically | Set 192.168.1.100, mask 255.255.255.0, gateway blank |
| 3. Route | The Ethernet adapter is disabled, or Wi-Fi is on a network using the same 192.168.1.x range | Enable the adapter. For the Wi-Fi, add a route for the terminal alone (below), or turn Wi-Fi off |
| 4. Ping | The terminal is not at the address you think | Read it off Menu > COMM. > Ethernet |
| 5. Port | The port or Comm Key was changed on the terminal, or another program is talking to it | Check Menu > COMM. > PC Connection, and close ZKBio Time.Net |
On that last row: we have not tested what this K40 does with two programs talking to it at once. We built so that it never happens, rather than find out during a class.
The trap at step two: an unplugged cable looks like a missing IP
The first version of our check looked at the addresses the PC holds. With the cable unplugged, it said no adapter was on 192.168.1.0/24 and told the person to set a static IP. The static IP was set. The cable was out.
Windows does not report a disconnected adapter’s address through an ordinary
lookup of the machine’s own addresses, so an unplugged cable looks exactly like a
missing setting. The check now reads the link state first, and asks each adapter
for its configured addresses directly with Get-NetIPAddress. “The static IP is
set, and will work once the cable is connected” became an answer of its own.
The other trap: a Wi-Fi on the same numbers
Plenty of home and office routers hand out 192.168.1.x addresses too. Our first check asked whether any adapter held an address on 192.168.1.0/24, so a laptop with its Wi-Fi on 192.168.1.x passed step two with the Ethernet never set. It passed step three as well, because that step asked only whether the address Windows would send from was on the terminal’s network, and the Wi-Fi’s was. The check now counts the Ethernet’s own addresses and nothing else.
The Wi-Fi can also take the traffic outright. Between two routes of the same length, Windows uses the one with the lower metric, and it sets the metric from link speed. Under Microsoft’s table a wired link at 100 Mb gets 35, and wireless is counted at half its advertised speed, so a Wi-Fi advertising 1.2 Gb gets 30 and wins 192.168.1.x away from the cable.
A ping on Windows can succeed at failing
If you script step four, do not trust the exit code. When nothing answers on the
local subnet, Windows can print “Destination host unreachable” as a reply from
your own address and exit with 0, which a script reads as success
(Microsoft Q&A).
Look for TTL= in the output instead. Only a real echo reply carries it.
A check on a timer has to finish inside its interval
The program asks every twenty seconds whether the terminal is there, and shows the answer in its top bar. With the cable out, one ask took 30.2 seconds. pyzk, the Python library that speaks the terminal’s protocol, spends ten seconds testing the port, ten opening the socket and ten waiting for a reply.
A thirty second check on a twenty second timer overlaps itself. The second ask found the first still holding the terminal and answered “busy”, so with nothing plugged in at all, the top bar switched between “not reachable” and “something else is using the terminal”.
The fix was a two second knock on port 4370 before handing over to the library. An unplugged terminal now answers in 2.2 seconds, and the top bar held “not reachable” through four checks in 75 seconds. If your own tool polls a terminal, time the failure case, not the working one. The working one is always fast.
The first laptop that was not ours
When the program went onto the lecturer’s own laptop, the connection check stopped at step two: cable connected, no adapter on 192.168.1.0/24.
That is the most likely failure on any new machine. A new laptop’s Ethernet port is set to get an address automatically, and a terminal on the other end of a cable does not hand out addresses, so Windows gives the port a 169.254.x.x address of its own and the terminal at 192.168.1.201 is never reached.
The usual fix, ours included above, is a static IP. It works, but it changes the whole port for the sake of one cable: with automatic addressing off, the same port stops working on an office network until someone turns it back on.
So the program now sets the laptop up itself, with one Windows permission prompt, and does it differently. It runs three commands on the adapter the check found:
netsh interface ipv4 set interface interface=12 dhcpstaticipcoexistence=enabled
netsh interface ipv4 add address name=12 address=192.168.1.100 mask=255.255.255.0
netsh interface ipv4 add route prefix=192.168.1.201/32 interface=12 store=persistent
- The first keeps the port automatic. It lets the adapter hold a manual address beside the one DHCP gives it. Without it, netsh’s own help says that adding an address turns DHCP off.
- The second adds the terminal’s network, with no gateway.
- The third is a route for the terminal alone. Windows takes the route with the longest matching prefix before it looks at any metric (Microsoft Learn), so a route to 192.168.1.201/32 sends the terminal’s traffic down the cable whatever the Wi-Fi is on.
12 is the adapter’s interface index, the ifIndex column of Get-NetAdapter, and
yours will be different. The index saves quoting a name like “Ethernet 2”, or a name
in another language. To run them yourself, open Command Prompt as administrator.
On the lecturer’s laptop, the prompt was answered Yes once and the program reached the terminal, and it still did after the laptop was restarted.
Two things we learnt building it. A process started with administrator rights cannot hand its output back to the program that asked for it, so the program decides whether it worked by reading the adapter again afterwards, never by an exit code. And Windows answers a No to the prompt with error 1223, but it gave us the same 1223 when the program it was asked to start did not exist. 1223 means “did not run”, not “the person said No”, so check the program is there before you ask.
To take it off again:
netsh interface ipv4 delete address name=12 address=192.168.1.100
netsh interface ipv4 delete route prefix=192.168.1.201/32 interface=12 store=persistent
If you would rather make the whole-port change, it is one command:
netsh interface ipv4 set address name="Ethernet" static 192.168.1.100 255.255.255.0
“Ethernet” is the adapter’s name as Windows shows it. Some laptops call theirs
“Ethernet 2”, and the check prints the name it found. Put the port back to automatic
with netsh interface ipv4 set address name="Ethernet" source=dhcp.
If you write code against the terminal itself, our notes on pyzk and this K40 cover what the library does not tell you.
What we have not confirmed
- This is one terminal model on one firmware. Other ZKTeco terminals share the same defaults in their guides, but we measured only this one.
- We did not compare cable types. The cable we used worked, and we did not check whether it was a crossover.
- Keeping DHCP beside a manual address is in netsh’s own help and in third-party write-ups, not on any Microsoft Learn page we could find. We have seen it work on one laptop, including after a restart. We have not yet seen it through a DHCP renewal, which happens when the same port is plugged into an office network.
- With the cable in and the Wi-Fi also on 192.168.1.x, traffic to other 192.168.1.x addresses, the Wi-Fi’s own router included, may prefer the cable. We read that from the metric table; we have not seen it happen.
- On an account that is not an administrator, the prompt asks for an administrator’s password. On a laptop the university manages, that may mean its IT office.
- The program is in use in one department and is not on our apps page yet. Its name stays off this site until a trademark search in Nigeria is finished.
Written by Adeboye Oluwatimileyin and Moses-Azuoru George, the two people who are Emberfig. We make money from AdMob inside the apps. This site carries no ads yet. You never pay us and we never sell your data.