last day (18 days later) » 

5:39 AM
anyone who wish to test my bot can go here: gist.github.com/TvoozMagnificent/…
(run the code)
(btw tio won't work)
 
5:53 AM
actually, no, we are in developement
and sunny's bot is being like, hi, sunny's bot, this is sunny's bot
 
6:07 AM
yah now its fixxed and running
I'd be really happy if anyone can help me test if it would work
 
 
1 hour later…
7:09 AM
@NobodyNeedsNames Some feedback: You don't need to check if ':' appears in the name before replacing, it will just do nothing anyway it it doesn't exist and make your code shorter
Installing a package in a python file is really bad practice
Don't use .read().decode(). Packets may be split arbitrarily and there is no guarentee you will get a entire packet at once. Also they may be joined
Instead read to a buffer and create your own seperator
length prefixed strings is a good way to do this
This all isn't that bad since you are just learning sockets, but keep it in mind if you ever need a more robust program
 
7:40 AM
@mousetail well my bot depends on that to check usernames
@mousetail I did that because apparently my friend doesn't know how to use pip
@mousetail lol its not my code
 
@NobodyNeedsNames No need, just use .replace it will do the same thng
 
oh wait ok brain fart
 
@NobodyNeedsNames Regardless of who wrote it it wont work
 
yah, what i mean is, i dont want to fix it because it doesn't currently have any problems
and i'm not sure if it will break after a fix
 
Try sending a message longer than 1024 bytes
Packets can get split even for smaller lengths
but at that point it's guarenteed
 
7:57 AM
oh ok, can you help me fix it or do i just remove .decode() and .encode()?
 
@NobodyNeedsNames Do you want the length prefixed or 0 byte sepereated solution?
 
wdym
i dont understand
 
Give me a moment I'm goiong to find my old chat program
 
import struct

def read(socket, callback):
    buff=""
    size=0
    while True:
        buff+=socket.read(1024)
        if len(buff)>=size + 4:
            if size>0:
                callback(buff[:size].decode('utf-8'))
            size,=struct.unpack("!L", buff[size:size+4])
            buff=buff[size+4:]
You should also use struct to prefix each message with it's length on the server side
@NobodyNeedsNames
 
8:07 AM
ok
so, i use that to replace
def listen_for_messages():
while True:
message = s.recv(1024).decode()
print(message)
# bot(message)
?
def listen_for_messages():
    while True:
        message = s.recv(1024).decode()
        print(message)
        # bot(message)
 
Yes
You will need a similar thing on the server
Also replace each instance of send(x) with send(struct.pack('!L', len(x))+x)
 
i've got no idea
plus, it tells me listen_for_messages() missing 2 required positional arguments: 'socket' and 'callback'
i know what it means but i have no idea how to fix it
 
I guess callback is print in your case
the socket is s in your case
 
ok, good
now its not giving me any output
 
Have you length prefixed the strings sent from the server?
 
8:15 AM
AttributeError: 'socket' object has no attribute 'read'
 
Sorry that should be recv()
I haven't actually tested this code, it's copied from my older project but that used a different socket library
 
I think I know how to fix this:

Traceback (most recent call last):
File "/usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 973, in _bootstrap_inner
self.run()
File "/usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 910, in run
self._target(*self._args, **self._kwargs)
File "/Users/luchang/client", line 54, in listen_for_messages
buff+=socket.recv(1024)
TypeError: can only concatenate str (not "bytes") to str
 
Replace buff="" with buff=b""
 
fudge
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 973, in _bootstrap_inner
self.run()
File "/usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 910, in run
self._target(*self._args, **self._kwargs)
File "/Users/luchang/client", line 58, in listen_for_messages
size,=struct.unpack("!L", buff[size:size+4])
NameError: name 'struct' is not defined
 
Did you import struct?
It was part of my original code
 
8:19 AM
fudgefudge no i think
it's not giving me any output
 
Did you length prefix on the server?
Basically what this does is every message will have a 4 byte length at the start
If you don't send a length it will interpret random data as the length which would typically be very long. So it will keep waiting for data until it has read that many bytes
 
how do I length prefix the server
current server code:
 
Like this:
Also replace each instance of send(x) with send(struct.pack('!L', len(x))+x)
 
import socket
from threading import Thread
from rich import print

print('\n'*100)

# server's IP address
SERVER_HOST = "0.0.0.0"
SERVER_PORT = 5002 # port we want to use
separator_token = "<SEP>" # we will use this to separate the client name & message

# initialize list/set of all connected client's sockets
client_sockets = set()
# create a TCP socket
s = socket.socket()
# make the port as reusable port
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# bind the socket to the address we specified
just tell me why would I want to do it
 
Right now since data is raw it just prevents random line breaks from appearing in your string
Or rare crashes with unicode characters
But most likely you soon want to send structured data, where a message break becomes much more important
 
8:25 AM
its still not outputting anything
 
Did you replace the client_socket.send() line on the server?
You can print what it thinks the value of "size" is to debug
If it's too big it's probably parsing incorrectly
 
oh, client_socket.send() could be in the client side: s.send(to_send.encode())
 
No
Or yes that might also work
Can you share the latest version of the client code?
Update the gist please it's much easier to read than here
 
sure
verymessy though
and server side if you need it: gist.github.com/TvoozMagnificent/…
should've added .py
 
Can you print the value of "size"?
 
8:32 AM
@mousetail ok...
 
I'm testing it on my laptop
Give me a few minutes
 
ok
```
a
15 (output)
num
name974 (output, my name is actually setted to name9743)
859447406 (output)
thing
god
what???
```
 
You will need to have the same prefixing logic on the server
I thought it might not be needed since server does little processing but sinc you replace the : token you need the strings decoded
So use the same function on the server
The issue is on the server you are attempting to decode the length prefix which is not actually text but raw binary
 
so um what should I do
 
Copy the same function to read length prefixed bytes to the server
 
8:40 AM
Has anyone here written a python module in rust?
 
You can do that?
 
Yes
I've never done it but there are libraries
 
Using C FFI on both sides should do
 
argh
Traceback (most recent call last):
File "/usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 973, in _bootstrap_inner
self.run()
File "/usr/local/Cellar/python@3.9/3.9.7/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 910, in run
self._target(*self._args, **self._kwargs)
File "/Users/luchang/server", line 45, in listen_for_client
client_sockets.remove(cs)
KeyError: <socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('192.168.0.9', 5002), raddr=('192.168.0.9', 54869)>
 
def listen_for_messages(socket=s, callback=print):
    buff=b""
    size=0
    while True:
        buff+=(socket.recv(1024))
        if size == 0:
            size,=struct.unpack("!L", buff[:4])
            buff=buff[4:]
        if len(buff)>=size:
            callback(buff[:size].decode('utf-8'))
            buff=buff[size:]
            size=0\
@NobodyNeedsNames slighly fixed version, no longer has a 1 message delay
The client works properly for me now
If you use the same function on the server the SEP replacement should work for you too
I would suggest getting rid of the SEP logic entirely since someone could just type <SEP> into their message and break the server
 
8:51 AM
I updated client.py and server.py, tell me what is wrong
(same gist)
gotta go, just ping me
 
@NobodyNeedsNames Don't modify the function I gave you at all, put the other logic all inside the callback
You can pass any function to the callback
in this case, you want the SEP logic and the code that actually sends the message to the other clients
 
9:31 AM
Is the accepted rule that no answer should be accepted these days?
 
9:49 AM
In most cases
 
10:11 AM
@mousetail Thanks a ton! Now works.
 
10:34 AM
@mousetail but whenever a user exits, the server errors
 
@NobodyNeedsNames Uncomment the try except code
 
oh ok
nice
how do i get the IP for the connection? I want to display something like X.X.X.X disconnected
 
I suggest a class for client, a convenient way to keep all the parameters a callback needs together
You can also nest functions for the same effect
 
10:52 AM
My chat bot is broken argh

Bot: https://gist.github.com/TvoozMagnificent/af4953f55ab3687d15bb4ce790c9175d
Bot Client Side: https://gist.github.com/TvoozMagnificent/d80d123b78195f29fcaa0d427c79b53e
Output:

Sunny's Bot: Hello! Sunny's Bot just arrived.
Type "help" for help.
Sunny's Bot: Hello! Sunny's Bot just arrived.
Type "help" for help.
hi
Sunny's Bot: Hello! Sunny's Bot just arrived.
Type "help" for help.
Sunny's Bot: Hello! Sunny's Bot just arrived.
Type "help" for help.
Sunny: hi
help
Sunny's Bot: Hello! Sunny's Bot just arrived.
(Type help for help is from the bot, Sunny's Bot: XXX lines are from the bot, Sunny: XXX lines are from me. All other lines are input)
Can someone help me? Very appeciated
 
Why do you create 2 functions with the same name?
You can use the same function twice, just pass a different callback as an argument
 
@mousetail where
oh, I didn't create a new one, it was there all the time
 
You define listen for messages 3 times
Use only the second one and pass a diferent parameter if you want different behavior
 
it's just I'm writing on the terminal and I am lazy so I decided I was not going to delete the
m
 
Anyway did you print the message? Might have a line break character or something similar at the end
 
11:08 AM
can you fix it for me? thnx
gotta go, just pin me
 
No sorry I can't. Need to start building a controller for the KOTH challange
 
11:32 AM
142 messages moved from The Nineteenth Byte
 
12:30 PM
@mousetail OK. No problem.
 
12:45 PM
@emanresuA thanks
 
1:21 PM
How come we were moved over??
 
2:05 PM
Which two was that?
 

  last day (18 days later) »