Konuyu Oyla:
  • Toplam: 0 Oy - Ortalama: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Python socket resim gönderirken EOFError hatası alıyorum
#21
Tam olarak hata bu: Smile
server.py
PHP Kod:
import socketthreadingpickle
socket.socket(socket.AF_INETsocket.SOCK_STREAM)
s.bind(("localhost",1234))
s.listen(10)
print(
"Server çalışıyor...")
def islem(baglantı):
    while 
True:
        try:
            
islemimg pickle.loads(baglantı.recv(100000).strip())
            if 
islem == "k":
                
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 islemargs = (baglantı,)).start() 
client.py
PHP Kod:
import socketpickle
socket.socket(socket.AF_INETsocket.SOCK_STREAM)
c.connect(("", ))
input("enter> ")
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. Smile

(server.py yi bir bilgisayarda, client.py de ayrı bir bilgisayarda denedim)
Ara
Cevapla
#22
İ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()

Turbobit Premium Link Çeviri | Turbobit Link Generator | http://turbobit.qpython.club
Cevapla
#23
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 923in _bootstrap_inner
    self
.run()
 
 File "C:\Users\SD\AppData\Local\Programs\Python\Python35\lib\threading.py"line 871in run
    self
._target(*self._args, **self._kwargs)
 
 File "C:\Users\SD\Desktop\server.py"line 10in islem
    islem
img pickle.loads(baglanti.recv(300000).strip())
EOFErrorRan 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 916in _bootstrap_inner
    self
.run()
 
 File "C:\Users\SD\AppData\Local\Programs\Python\Python36\lib\threading.py"line 864in run
    self
._target(*self._args, **self._kwargs)
 
 File "C:\Users\SD\Desktop\sw.py"line 8in islem
    islem
img pickle.loads(baglanti.recv(300000).strip())
_pickle.UnpicklingErrorpickle 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:
abbağ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.
Ara
Cevapla
#24
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.
Turbobit Premium Link Çeviri | Turbobit Link Generator | http://turbobit.qpython.club
Cevapla
#25
Cevaplar için çok saolun. Smile 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

socket.socket(socket.AF_INETsocket.SOCK_STREAM)
s.bind(("localhost"1236))
s.listen(5)
caddr s.accept()
datas c.recv(1024)
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

socket.socket(socket.AF_INETsocket.SOCK_STREAM)
s.connect(("", ))
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() 
Ara
Cevapla
#26
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.
Turbobit Premium Link Çeviri | Turbobit Link Generator | http://turbobit.qpython.club
Cevapla
#27
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

socket.socket(socket.AF_INETsocket.SOCK_STREAM)
s.bind(("localhost"1236))
s.listen(5)
caddr s.accept()
datas c.recv(1024)

print(
datas)
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
socket.socket(socket.AF_INETsocket.SOCK_STREAM)
s.connect(("localhost"1236))
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 7in <module>
 
   s.send("Content-Length: 123\r\n\r\n")
TypeErrora bytes-like object is requirednot 'str'
[Finished in 0.8s
Ara
Cevapla
#28
Bilemiyorum hata almaman gerekirdi
Turbobit Premium Link Çeviri | Turbobit Link Generator | http://turbobit.qpython.club
Cevapla
#29
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..
Ara
Cevapla
#30
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
socket.socket(socket.AF_INETsocket.SOCK_STREAM)
s.bind(("localhost"1234))
s.listen(5)
caddr s.accept()
image_datasd1d2 c.recv(1024)
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
socket.socket(socket.AF_INETsocket.SOCK_STREAM)
c.connect(("localhost"1234))
open("image.jpg""rb")
img_data f.read()
data1 "hello"
data2 "server"
c.send(img_data,data2,data3)
f.close()
c.close() 
Ara
Cevapla

{lang: 'en'}


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  python float sayılarla (para) çalışmak ahgonlum 2 99 04-06-2020, Saat: 19:32
Son Yorum: ahgonlum
Question Python Dili Soru & Cevap gecemor 1,448 791,372 02-06-2020, Saat: 22:48
Son Yorum: gecemor
  Socket Hakkında SD-16 9 1,395 04-10-2019, Saat: 06:54
Son Yorum: oktay811
  Python ile yüz degistirme SD-16 1 731 01-10-2019, Saat: 11:41
Son Yorum: ahgonlum
  Python UDP ile internet paketsiz dosya indirme, Turkcell Rosenrot 2 1,020 29-08-2019, Saat: 23:09
Son Yorum: aras5757

Hızlı Menü:


Konuyu Okuyanlar: 1 Ziyaretçi
Change Theme