Socket ile resim, dosya gonderme

Merhaba.

Aslında socket modülüyle gönderilip alınan veri bytes(ikili veri) türündedir. Yani hem metin, hem resim, hem de diğer türlerdeki her veriyi bu modülle gönderebilirsiniz. socket modülünün sayfasındaki recv ve send metodlarına bakarsanız bytes nesnesiyle çalıştıklarını görebilirsiniz: https://docs.python.org/3/library/socket.html

İyi çalışmalar.

3 Beğeni

ozellikle boyle ipucunu verip hazira yonetlmemenizi cok takdir ediyorum.

2 Beğeni

evet bytes olarak gonderiliyor acaba ben c.sendall(bytes(resim.ismi)) diyerek resmi gondere bilirmiyim?

Aşağıdaki projemi inceleyebilirsiniz.
https://github.com/laszlokuehl/sync

Açıkçası böylesi kolayıma geliyor. :smile:

bytes sınıfının imzasına bakarsanız bu sınıfın dosya adı değil de source(kaynak) aldığını görebilirsiniz. Hatta ikinci argüman olarak encoding(kodlama) verebilirsiniz. Yani göndereceğiniz resim dosyasını önce open gömülü fonksiyonu ile okumalı, daha sonra bytes sınıfı ile bytes veri türüne dönüştürüp öyle göndermeniz gerekir.

İyi çalışmalar.

2 Beğeni

Merhaba.

Aşağıdaki adımlar üzerinde biraz düşünmenizi öneririm. Bu adımları bir socket uygulamasının neresine nasıl dahil edeceğinizi bulmaya çalışın. Şayet yine yardıma ihtiyacınız olursa, yazdığınız kodları buraya yazın, onlar üzerinde değişiklikler yapmaya çalışalım.

Dosya gönderecek olan bilgisayar için:

  1. Dosyayı gönderecek olan kişinin bilgisayarında gönderilecek olan dosyayı byte verisi olarak okuyun.
  2. Okunmuş veriyi bir değişkene atayın.
  3. Bu değişkeni tanımladıktan sonra, (örn: değişken ismi data ise, while data gibi) bir döngüye sokun.
  4. Döngü içinde diğer bilgisayara değişkeni send komutuyla gönderin.
  5. Döngünün son satırında okunmuş dosyayı tekrar aynı değişkene atayın.
  6. Döngüden çıkın ve dosyayı kapatın.

Dosyayı alacak olan bilgisayar için:

  1. While döngüsü içinde göndericileri kabul edin (c, addr = s.accept()
    gibi). Aynı zamanda göndericiden gelecek veriyi bir değişkene atayın (data = c.recv(1024) gibi).
  2. Yazma modunda bir dosya açın.
  3. While döngüsü içinde yeni bir while döngüsü oluşturun, ancak bu kez while döngüsü değişkene göre ayarlansın (while data gibi)
  4. Veri aktarımı sürdüğü sürece, yazma modunda açtığınız dosyaya bu değişkeni yazdırın. Bu döngünün son satırında değişkeni tekrar tanımlayın (data = c.recv(1024) gibi)
  5. Data döngüsünden çıkın ve dosyayı kapatın.

Dosyayi byes verisi gibi okumak nasil oluyor? mesele diyelimki karsi tarafda olan bir resmi veya dosya.txt nasil bytes yapa bilirim? input() ile girilen deyeri bytes yapa biliyorumda resmi veya dosyayi bilmiyorum

Örnek:

Byte satırlarını okumak icin:
dosya = open ("resim.jpg", "rb")

Byte satırlarını yazmak için:
dosya = open ("resim.jpg", "wb")

2 Beğeni

Anladim tesekkur ederim

iyi gunler kardes ben bir sorunla karsilasdim onu cozemedim bir resmi open("resim.jpg", "rb") diyerek aciyorum onu bytes yapdikdan sonra karsi tarafa gonderiyorum fakat resmin hacmi buyuk oldugundami anlamadim 1023 karakter gidiyor fazlasi gitmiyor diye resim hata veriyor karsi tarafda socket modulu belli bir boyutdami dosya transferin izin veriyor?

Tekrar merhaba.

Sizin için bir sakıncası yoksa kodları burada paylaşın, bir bakalım.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#server dosyasi

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 12347
s.bind((host, port))
s.listen(10)  # -> 10 istemci bağlanabilir.
c, addr = s.accept()

dosya=open("resim.jpg", "rb")
dosya2=dosya.read()
print(type(dosya2))
print(len(dosya2))
dosya.close()
s.sendall(dosya2)
exit()
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

#client.py

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 12347
s.connect((host, port))
data = s.recv(1024)[1:]
print(type(data))
print(len(data))
dosya=open("resim3.jpg", "wb")
dosya.write(data)
dosya.close()
exit()

Bahsettiğim while döngüsünü kullanmamışsınız. Size çalışan bir kod veriyorum, bu kodları bir inceleyin isterseniz.

Bu örnek, istemcilerden sunucuya dosya göndermekle alakalı. Sunucu devamlı açık kalır; bunun için sunucu makine while True gibi bir sonsuz döngüye sokulur. istemcilerin ise sunucuyla bağlantısı dosya gönderdikten sonra kesilir, bu yüzden onları sonsuz döngüye sokmak gerekmiyor.

Dosya gönderme ve alma işlemi de ayrıca while döngüsüne sokulur, çünkü veri alma işlemi 1024 byte satırı üzerinden olacağı için, bütün byte satırları okunana kadar dosya gönderme ve alma işlemi devam ettirilir.

server.py’nin kodları:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket
import os

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("", 12345))
s.listen(10)

# Gelen dosyaların hepsi 'dosya' isminde kaydedileceği
# için dosya isimlerine numara ekleyelim.
say = 0
for i in os.listdir(os.getcwd()):
    if i.startswith("dosya"):
        say += 1
dosya_no = say

print("Sunucu açıldı...\nİstemciler bekleniyor...")

while True:
    c, addr = s.accept()
    print('\n{} bağlandı.'.format(addr))
    datas = c.recv(1024)
    f = open("dosya{}.jpg".format(dosya_no), "wb")
    while datas:
        f.write(datas)
        datas = c.recv(1024)
    f.close()
    print("dosya{} alındı...".format(dosya_no))
    dosya_no += 1
    continue

client.py’nin kodları:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("", 12345))

f = open("dosya.jpg", "rb")
data = f.read()

while data:
    s.send(data)
    data = f.read()

f.close()
print("Dosya gönderildi.")

Döngüler ile yapmak yerine, veri göndermeden önce verinin uzunluğunu gönderip, buna göre recv fonksiyonunu kullanabilirsiniz.

Örnek: https://github.com/laszlokuehl/sync/blob/master/sync.py#L107-L133

Hocam merhabalar, konu üzerinden uzun zaman geçmiş yine de bir soru sormak istiyorum.
Bu şekilde 1-2 mb’lık bir fotoğraf ne kadar sürede transfer edilebilir?
Teşekkürler.

İnternet ağının sağladığı hıza bağlı. socket kütüphanesi bunun üstüne pek bir süre eklemez.

python send image server Code Example (codegrepper.com)

Peki, bu haberleşme internet bağlantısı olmadan da yapılabilir mi? Yani iki cihazı yalnızca wifi ile birbirlerine bağlayarak da bu şekilde bir transfer yapılabilir mi? Yapılamıyorsa yalnızca wifi ile birbirlerine bağlayarak nasıl fotoğraf gönderebiliriz?
Teşekkürler.

Kendi kapalı ağınızı kurmanız mümkün olsa gerek ama nasıl yapılır bilmiyorum.


Yapılamıyorsa nasıl yapılabileceğini mi soruyorsunuz?