[英]How to correctly send image through socket using python client and C server
I am programming chat-like application in which user apart from sending messages can also send pictures.我正在编写类似聊天的应用程序,其中用户除了发送消息之外还可以发送图片。 Only problem is that I am not sure how should I approach image sending.
唯一的问题是我不确定我应该如何处理图像发送。 Main idea is that user chooses image writing
/send image.jpg
in the console, and then image is sent via socket.send(image.jpg)
.主要思想是用户在控制台中选择图像写入
/send image.jpg
,然后通过socket.send(image.jpg)
发送图像。 Sending image works fine for me, but my C server is getting data input from client in seperate "packages" because of buffor, but when I add them, they don't match the size of my image (eg my image is 73kb but server gets 29kb from two separate "packages" 20kb + 8.5kb).发送图像对我来说很好,但是我的 C 服务器由于缓冲区而从单独的“包”中从客户端获取数据输入,但是当我添加它们时,它们与我的图像大小不匹配(例如我的图像是 73kb 但服务器从两个单独的“包”20kb + 8.5kb 中获取 29kb)。 And the second problem is how to send this data further, I thought that maybe there is some way of passing buffor with actual image binary data and send it to the rest of my clients in Python.
第二个问题是如何进一步发送这些数据,我认为也许有某种方法可以通过实际图像二进制数据传递缓冲区并将其发送到 Python 中我的客户的 rest。 My buffer is 20480 bytes.
我的缓冲区是 20480 字节。
Sending from client.py:从 client.py 发送:
elif "/send " in buffer:
fileArr = buffer.split(' ') #filearr = ["/send", "image.jpg"]
file = open(fileArr[1], "rb").read()
s.send(fileArr[0].encode()) #metadata that im sending image file
time.sleep(0.2)
s.send(file) #sending my file
time.sleep(1)
print("Image sent!")
My server.c receiving and sending:我的 server.c 接收和发送:
void send_message(char *s, int uid){
pthread_mutex_lock(&clients_mutex);
for (size_t i = 0; i < MAX_CLIENTS; i++) {
if(clients[i]){
if(clients[i]-> uid != uid){
if(write(clients[i]->sockfd, s, strlen(s)) < 0){
perror("");
printf("Write to descriptor failed \n");
break;
}
}
}
}
pthread_mutex_unlock(&clients_mutex);
}
if(strstr(buffer, "/send") != NULL || receive > 128){
if(strstr(buffer, "/send")){
buffer[0] = '\0';
}
recv(cli->sockfd, buffer, sizeof(buffer), 0); // Receiving my image and saving it to buffer
printf("receiveing img");
send_message(buffer, cli->uid); // Sending my buffer further to client
printf("sending image\n" );
And my client.py receiving:而我的 client.py 接收:
def recvDataLoop():
while True:
reply = s.recv(buffer_sz)
if reply:
print("Got reply");
flag = 0
try:
reply = reply.decode()
if flag != 1 and "joined the chat" in reply or "has left" in reply:
print(reply)
elif flag != 1 and "|" in reply:
replyArr = reply.split("|")
time.sleep(0.1)
print("{}: {}".format(replyArr[0],replyArr[1]))
except:
print("Encoded") #If data received and it cannot be decoded, its <bytes>
try:
f = open("cat4.jpg", "ab").write(reply) #If image exists, write data to existing image
except:
f = open("cat4.jpg", "wb").write(reply)
I needed to make this try-except blocks because that when data is received, it's received in packages so when I get it, I need to write it to the end of my cat4.jpg file.我需要制作这个 try-except 块,因为当接收到数据时,它是在包中接收的,所以当我得到它时,我需要将它写入 cat4.jpg 文件的末尾。
Socket rx/tx functions normally return the actual number of bytes transmitted.套接字 rx/tx 函数通常返回实际传输的字节数。 Thus the proper way of doing the rx/tx is to call the function in a loop, while accumulating return value and moving the buffer start pointer.
因此,执行 rx/tx 的正确方法是在循环中调用 function,同时累积返回值并移动缓冲区起始指针。 Moreover, when dealing with binary data - such as image data - null termination assumption is wrong and truncates the data in wrong length;
此外,在处理二进制数据时 - 例如图像数据 - null 终止假设是错误的,并且会截断错误长度的数据; it may also trigger array index out-of-bounds related exceptions.
它还可能触发数组索引越界相关异常。 You need to explicitly specify rx/tx byte count (
strlen
is wrong).您需要明确指定 rx/tx 字节数(
strlen
是错误的)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.