Üst Üye
 
Üyelik Tarihi: 04-07-2018
Yorum Sayısı: 163
Konu Sayısı: 35
Rep Puanı:
0
16-05-2020, Saat: 18:48
(Son Düzenleme: 16-05-2020, Saat: 18:55, Düzenleyen: SD-16.)
Tam olarak hata bu: 
server.py
PHP Kod:
import socket, threading, pickle s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("localhost",1234)) s.listen(10) print("Server çalışıyor...") def islem(baglantı): while True: try: islem, img = pickle.loads(baglantı.recv(100000).strip()) if islem == "k": f = open("C:\\Users\\user\\Desktop\\{}.jpg".format("resim"), "wb") f.write(img) f.close() print("resim eklendi...") s.close() else: pass except (ConnectionResetError,ValueError,EOFError,KeyError): pass baglantı, adres = s.accept() threading.Thread(target = islem, args = (baglantı,)).start()
client.py
PHP Kod:
import socket, pickle c = socket.socket(socket.AF_INET, socket.SOCK_STREAM) c.connect(("", )) input("enter> ") f = open("C:\\Users\\SD\\Desktop\\image.jpg", "rb") img_data = f.read() data = pickle.dumps(("k",img_data)) c.sendall(data) f.close() c.close() print("resim gönderildi") input()
hata ise pickle modülünün gelen verinin hepsini alamaması, ama 1-2 kb lık dosyaları alıyor. buradan da https://stackoverflow.com/questions/2396...-underflow bu konuyu buldum ama koduma uyarlıyamadım. Bu kodu çalıştırırsam kendi gerçek kod dosyamda da çalıştırabilirim ve sorun çözülür.
(server.py yi bir bilgisayarda, client.py de ayrı bir bilgisayarda denedim)
İyi de ben sana daha önce send() ile ilk önce boyut bilgisini gönderebilirsin demiştim, sonraki send() ile de datayı gönderebilirsin.
Bir ikincisi zaten önceki verdiğimiz örneklerdeki gibi while data diyerek "eğer data varsa dönmeye devam et" diyorduk, sen burada while True diyerek sonsuz bir döngüye girmişsin ama durdurmayı düşünmemişsin. Bu durumda break veya return ile durdurmayı deneyebilirdin. (dikkat: return ile durduracaksan döngü bir fonksiyon içinde olmalı, o yüzden buradakine uygun olduğundan return alternatif gösterdim)
Ve daha da önemlisi önceki verdiğimiz örneklerde her döngüde recv() ile datayı okuduğumuz için öncesinden herhangi bir boyut bilgisi göndermemize gerek kalmıyordu. Yani eğer gönderilen dosya boyutu fazla ise mesela 100kb, bu da 102400 byte yapar ve recv(100) bile olsa döngü devam ettikçe okurdu, recv() boş gelince de döngü sonlanırdı. Böylece boyut bilgisi göndermeye gerek kalmazdı. Haa göndermek istiyosan da dediğim gibi ilk gönderdiğin send() ile bilgiyi alır ikincisi ile de resimi gönderirdin.
döngü içerisinde s.close() yapman demek döngü bitmeden server'ı sonlandırmaya çalışman demek, bunun yerine bağlantı.close() yapmalısın (işin bittiyse tabi)
Kısacası sana bir önceki verdiğim örneği uyarlamaya çalışsan bence daha verimli olacaktır. Ama yine de bu son verdiğin kodları biraz editleyerek kendi bilgisayarımda test ettim, ben olsam böyle kullanmam ama belki düzeltmen gereken yerleri dikkate alırsın diye yine senin verdiğin üzerinden gittim.
server.py
import socket, threading, pickle
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("localhost",1234))
s.listen(10)
print("Server calisiyor...")
def islem(baglanti):
while True:
try:
islem, img = pickle.loads(baglanti.recv(100000).strip())
if islem == "k":
f = open("C:\\Users\\EmRe\\Desktop\\{}.jpg".format("resim"), "wb")
f.write(img)
f.close()
print("resim eklendi...")
# s.close() # Yanlış kullanım
baglanti.close() # Doğru kullanım
break # while True olduğunda break veya return ile döngüyü durdurmalısın
else:
pass
except Exception as error: # Burayı kendime göre düzenlemiştim
print error
baglanti, adres = s.accept()
threading.Thread(target = islem, args = (baglanti,)).start()
Üst Üye
 
Üyelik Tarihi: 04-07-2018
Yorum Sayısı: 163
Konu Sayısı: 35
Rep Puanı:
0
17-05-2020, Saat: 00:10
(Son Düzenleme: 17-05-2020, Saat: 00:47, Düzenleyen: SD-16.)
send ile önce veri boyutunu gönderip ardından veriyi gönderme kısmını inceledim ama yapamadım, kodları da değiştire değiştire daha farklı oldu. s.close() yi program hata verdiğinde port açık kalmasın diye yazmıştım öyle kalmış. Şuan attığınız kodları denedim aynı bilgisayarda çalışınca büyük-küçük dosya fark etmeksizin gönderiyor ama iki bilgisayarda biri server biri client olunca olmuyor. mesala 280kb lık bir dosya gönderdim ama bu hatayı verdi:
PHP Kod:
Server calisiyor... Exception in thread Thread-1: Traceback (most recent call last): File "C:\Users\SD\AppData\Local\Programs\Python\Python35\lib\threading.py", line 923, in _bootstrap_inner self.run() File "C:\Users\SD\AppData\Local\Programs\Python\Python35\lib\threading.py", line 871, in run self._target(*self._args, **self._kwargs) File "C:\Users\SD\Desktop\server.py", line 10, in islem islem, img = pickle.loads(baglanti.recv(300000).strip()) EOFError: Ran out of input
recv kısmında 300000 yazılı, en fazla 2kb lık gönderiyor, gine büyük dosyalar da bu hatayı veriyor. Bu hatayı da sormuştum döngü kullanın demiştiniz onuda yapamadım. Yani şuan ne yapsam bir türlü programı tam çalıştıramıyorum. Acaba düzenlediğiniz kodların içine döngüyü kullanma kısmını da ekleyebilir misiniz?
ve server dosyamdaki python sürümü 3.5 client ise 3.6 sorun bundan olabilir mi bi ihtimal?
-az önce 3.5 kaldırıp 3.6 yükledim bu sefer de daha önce aldığım hatayı verdi:
PHP Kod:
Server calisiyor... Exception in thread Thread-1: Traceback (most recent call last): File "C:\Users\SD\AppData\Local\Programs\Python\Python36\lib\threading.py", line 916, in _bootstrap_inner self.run() File "C:\Users\SD\AppData\Local\Programs\Python\Python36\lib\threading.py", line 864, in run self._target(*self._args, **self._kwargs) File "C:\Users\SD\Desktop\sw.py", line 8, in islem islem, img = pickle.loads(baglanti.recv(300000).strip()) _pickle.UnpicklingError: pickle data was truncated
daha önceden sadece string gönderiken böyle gönderiyordum:
PHP Kod:
data = "\n",join(("a","b","c"))
ve server da böyle çözüyordun:
PHP Kod:
a, b, c = bağlantı.encode().split("\n")
sonra string yanına resim gönderince aynı anda string ve byte gönderemediği için pickle yi kullandım ondada bu hataları veriyor ve bir türlü çalıştıramıyorum.
bak ŞURADA verdiğim örnekteki server.py dosyasını bir sunucuya attım ve 771KB lık bir resim gönderdim ve sorunsuz olarak gönderdi, server tarafından da kaydedildi. Serverdan kaydedilen resimi bilgisayarıma indirip kontrol ettim sorun yok. Artık senin kullandığın server-client iletişiminde ne gibi bir sorun var bilemiyorum. Zaten gereken tüm açıklama ve örnekleri verdiğimi düşünüyorum.
Dediğim gibi illa recv(30000) gibi yüksek rakam vermeye gerek yok, recv(10) bile yapsan döngü ile okutursun. Dosya boytutu göndereceksen de bunun yolu bilgileri pickle içine gömmek değil, Content-Length header'ı ile göndermektir.
Üst Üye
 
Üyelik Tarihi: 04-07-2018
Yorum Sayısı: 163
Konu Sayısı: 35
Rep Puanı:
0
17-05-2020, Saat: 13:16
(Son Düzenleme: 18-05-2020, Saat: 13:30, Düzenleyen: SD-16.)
Cevaplar için çok saolun.  sonunda verdiğiniz örnekler ile gönderme işlemini yaptım. Son olarak resmin yanında birde nasıl metin gönderip karşı taraftan alabilirim?
PHP Kod:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("localhost", 1236)) s.listen(5) c, addr = s.accept() datas = c.recv(1024) f = open("C:\\Users\\SD\\Desktop\\resim.jpg", "wb") while datas: f.write(datas) datas = c.recv(1024) f.close() c.close() s.close()
PHP Kod:
# -*- coding: utf-8 -*- import socket,pickle
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("", )) f = open("deneme.jpg", "rb") img = f.read() data = pickle.dumps((img)) s.send("a","b","c",img)#Burada metinde gönderip karşıda kullanmak istiyorum f.close()
metini dediğim şekilde header ile gönderebilirsin aslında ama yine de tek seferde göndermek istiyosan send_multipart() metodunu da kullanabilirsin. Veya bir json oluşturup içerisine bilgileri ve resimi yerleştirip pickle ile iletmeyi sonra serverda load edip bilgileri ayrıştırmayı deneyebilirsin. Aslında bu konuda kasik yönetmleri araştırıp request metodlarını ve headerları incelemen gerekir.
Üst Üye
 
Üyelik Tarihi: 04-07-2018
Yorum Sayısı: 163
Konu Sayısı: 35
Rep Puanı:
0
17-05-2020, Saat: 21:08
(Son Düzenleme: 17-05-2020, Saat: 21:53, Düzenleyen: SD-16.)
yalnız send_multipart() socket de tanımlı değil. Eski sürümlerinde mi var?
verdiğiniz bu örneği denedim:
server.py
PHP Kod:
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("localhost", 1236)) s.listen(5) c, addr = s.accept() datas = c.recv(1024)
print(datas) f = open("C:\\Users\\SD\\Desktop\\resim.jpg", "wb") while datas: datas = c.recv(1024) f.write(datas) f.close() c.close() s.close()
client.py
PHP Kod:
# -*- coding: utf-8 -*- import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("localhost", 1236)) f = open("deneme.jpg", "rb") img = f.read() s.send("Content-Length: 123\r\n\r\n") s.send(img) f.close()
bu hatayı verdi:
PHP Kod:
Traceback (most recent call last): File "C:\Users\SD\Desktop\cl.py", line 7, in <module> s.send("Content-Length: 123\r\n\r\n") TypeError: a bytes-like object is required, not 'str' [Finished in 0.8s]
Bilemiyorum hata almaman gerekirdi
Kıdemli Üye
  
Üyelik Tarihi: 03-06-2016
Yorum Sayısı: 232
Konu Sayısı: 6
Rep Puanı:
6
string yerine byte olarak yollamalısın diyor . başına b koyarsan byte olmuş olur. merak ettim bunu hızlı dosya falan indirme için mi yapıyorsun? @ SD-16
Kod:
s.send(b"Content-Length: 123\r\n\r\n")
python ve javascript dünyada en çok yazılan iki dil.
c kadar hızlı python kadar syntaxı kolay olan julia da geleceğin dilleri arasında..
Üst Üye
 
Üyelik Tarihi: 04-07-2018
Yorum Sayısı: 163
Konu Sayısı: 35
Rep Puanı:
0
18-05-2020, Saat: 20:02
(Son Düzenleme: 18-05-2020, Saat: 21:50, Düzenleyen: SD-16.)
Hızlı dosya indirmek için değil. b koymuştum ama olmamıştı. Sadece servera resim kodlarını yanında metin de göndermeye calisiyorum. Aynı anda göndermeyi yada tek tek göndermeyi hangisi olursa, denemeler yapmama rağmen de çözemedim.
Bu şekilde yapmaya çalışıyorum:
PHP Kod:
#server.py import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(("localhost", 1234)) s.listen(5) c, addr = s.accept() image_datas, d1, d2 = c.recv(1024) f = open("C:\\Users\\SD\\Desktop\\image.jpg", "wb") while image_datas: f.write(image_datas) image_datas = c.recv(1024) print(d1,d2) f.close() c.close() s.close()
PHP Kod:
#client.py import socket c = socket.socket(socket.AF_INET, socket.SOCK_STREAM) c.connect(("localhost", 1234)) f = open("image.jpg", "rb") img_data = f.read() data1 = "hello" data2 = "server" c.send(img_data,data2,data3) f.close() c.close()
|