Socket ile byte dışı data aktarımı

Amacım serverin olduğu bir bilgisayara başka bir bilgisayardaki client ile bağlanıp, clientin olduğu bilgisayardan byte dışındaki bir veri tipini göndermek
Diğer bir deyişle bir bilgisayardan diğer bilgisayarın ekranını socket bağlantısı kurarak izlemek fakat yapamıyorum lütfen yardım edin.

Kurmaya çalıştığım mantık şuydu:
Opencv de ekran kaydı alınırken kullanılan veriyi socket ile servere gönderip aynı veriyi serverde opencv ile izlemekti fakat opencv de ekran kaydı için kullanılan veri numpy kütüphanesine ait bir veri tipi olduğu için byte veri tipine dönüştüremiyorum. Dönüştüremeyincede socket ile veriyi yollayamıyorum.

Server

import socket

# Bir tane socket nesnesi oluşturulur.
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Yerel makinenin ismi alınır.
host = socket.gethostname()
# Servis için bir tane port numarası belirlenir.
port = 12347
# Yerel makine ismi ile port numarası bağlanır.
s.bind((host, port))
# İstemci bağlantısı için port dinlemesi başlatılır.
s.listen(10)  # -> 10 istemci bağlanabilir.
# istemci ve adresi kabul edilir.
c, addr = s.accept()
# Bağlanan istemciye hoşgeldin mesajı gönderilir.
c.sendall(bytes("Merhaba!".encode("utf-8")))
# Bağlantı adresi sunucu ekranına bastırılır.
print('{} bağlandı.'.format(addr))
# Sunucunun sürekli açık kalması için sonsuz döngüye ihtiyacımız var.
# Veya mesaj adediyle veya başka parametrelerle döngü sonlu da olabilir...
while True:
    # İstemciden gelen, ara bellek boyutu 1024 olan,
    # byte tipindeki mesaj stringe dönüştürülür.
    # Bu string'in ilk elemanı hariç diğer elemanları data isminde
    # bir değişkene atanır.
    data = str(c.recv(1024))[1:]
    # Eğer istemciden mesaj gelmişse
    if data:
        # İstemcinin mesajını bastır.
        print("İstemci: {}".format(data))
        # İstemciye göndereceğimiz mesajı yazalım.
        respond = input("Sunucu: ").encode("utf-8")
        # Mesaj "q" ise programdan çıkalım.
        if respond == b"q":
            exit()
        # Diğer her türlü durumda mesajımız karşı tarafa gitsin.
        else:  # İstemciye mesaj byte verisi olarak gönderilir.
            c.sendall(bytes(respond))

Client

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname()
port = 12347

# Sunucuya bağlanalım.
s.connect((host, port))

# İstemci sunucuya bağlandıktan sonra
# Sunucunun yaptığı işin aynısını yapıyor.
while True:
    data = str(s.recv(1024))[1:]
    if data:
        print("Sunucu: {}".format(data))
        respond = input("Istemci: ").encode("utf-8")
        if respond == b"q":
            exit()
        else:
            s.sendall(bytes(respond))

OpenCv

import numpy as np
import cv2
from PIL import ImageGrab

fourcc = cv2.VideoWriter_fourcc('X','V','I','D') #you can use other codecs as well.
vid = cv2.VideoWriter('record.avi', fourcc, 8, (500,490))
while(True):
    img = ImageGrab.grab() #x, y, w, h
    img_np = np.array(img)
    #frame = cv2.cvtColor(img_np, cv2.COLOR_BGR2GRAY)
    vid.write(img_np)
    cv2.imshow("frame", img_np)
    key = cv2.waitKey(1)
    if key == 27:
        break
vid.release()
cv2.destroyAllWindows()

Kodları fotoğraf şeklinde atmanız yanlış, kodlarınızı normal şekli ile ``` arasına alıp sorunuza ekleyin ki biz de deneme yaparken kodunuzu kolayca kopyalayabilelim.

1 Beğeni

forumu ilk defa kullanıyorum kod blokları arasına almayı denedim fakat bulamadım

Dediğim gibi kodun en başına ve sonuna ``` koymanız yeterli.

tamamdır yaptım teşekkürler

1 Beğeni

Standart kütüphanede bulunan pickle modülü sorununuza çok iyi bir çözüm. Bu kütüphane python nesnelerini bytes türüne dönüştürmemizi ve daha sonra tekrar asıl haline çevirmemizi sağlamaktadır. Bildiğiniz gibi socket kütüphanesi ile de internet üzerinden sadece bytes türündeki nesneleri gönderebiliyoruz. Bir örneğin kendi kodunuzda gerekli değişimleri yapmanız için yeterli olacağını düşünüyorum:

>>> import pickle
>>> import numpy
>>> a = numpy.array(( 1,2,3, (4,5,6) ))
>>> byte_hali = pickle.dumps(a) # a değişkenini bytes'a dönüştürüyoruz
>>> byte_hali
b'\x80\x03cnumpy.core.multiarray\n_reconstruct\nq\x00cnumpy\nndarray\nq\x01K\x00\x85q\x02C\x01bq\x03\x87q\x04Rq\x05(K\x01K\x04\x85q\x06cnumpy\ndtype\nq\x07X\x02\x00\x00\x00O8q\x08K\x00K\x01\x87q\tRq\n(K\x03X\x01\x00\x00\x00|q\x0bNNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK?tq\x0cb\x89]q\r(K\x01K\x02K\x03K\x04K\x05K\x06\x87q\x0eetq\x0fb.'
>>> asıl_hal = pickle.loads(byte_hali) # bytes'i tekrar asıl haline döndürüyoruz
>>> asıl_hal
array([1, 2, 3, (4, 5, 6)], dtype=object)
>>> asıl_hal == a
array([ True,  True,  True,  True])
2 Beğeni

Çok teşekkürler üstad :slight_smile:

import numpy

a = numpy.array([[1, 2, 3], [3, 4, 5]], dtype=numpy.int32)
print(a)
# [[1 2 3]
#  [3 4 5]]

bs = a.tobytes()
print(bs)
# b'\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00'

b = numpy.frombuffer(bs, dtype=numpy.int32).reshape(2, 3)
print(b)
# [[1 2 3]
#  [3 4 5]]
1 Beğeni

Eğer arrayda saklayacağımız verinin türü belli ise @aib’in yöntemi çok daha hızlı ve kullanışlı. pickle modülü ise daha genel amaçlıdır ve çoğu nesne ile çalışmaktadır.

peki bir şey daha soracağım socket ile bir server yaptık birden fazla client zamanı belli olmadan servere bağlandılar ve sürekli bu verileri gönderdiler ben hangisinden veriyi alacağımı nasıl seçeceğim. yani yapmak istediğim şu:
server olarak kendi bilgisayarımı kullanacağım client olarakda 3 4 tane farklı ip deki farklı yerlerdeki bilgisayarların ekranını izleyeceğim fakat bunu yaparken hangisini ne zaman seçeceğimi bilmiyorum

Kac tane accept varsa o kadar baglanti. Kodda bir accept goruyorum, o halde birden fazla baglanti acilmasi mumkun degil.

Coklu baglanti modelleri arasindan en kolayi thread-per-client/thread-per-connection olsa gerek. (Her baglantiya kendi thread’ini vermek. accept'ten sonra yapabilirsin mesela)

@aib’in de dediği gibi en kolay ve problem yaşamayacağınız yol her client için bir thread çalıştırmak. Ancak önemli olan bir ayrıntıyı vermemişsiniz, client’ler sizin wifi’nize mi bağlı olacak -yani hepsi aynı LAN’da mı olacak- yoksa herhangi bir yerde mi olacaklar. Örneğin kendi evinizdeki bilgisayardan uzaktaki başka bir bilgisayar ile bağlantı kurmak için ya server hosting kullanmalı ya da port yönlendirme yapmalısınız.

1 Beğeni

Port yönlendirme yapacağım uzak bağlantı alacağım. Amacım şu:
kendi bilgisayarımda bir ftp sunucusu daima açık olacak. Yazılan şeyler ve belirlediğim şartlara göre ekran görüntüleri gelecek. Buraya kadar yaptım ftp de gelen bağlantıları tek tek kabul etmeme veya işlem yaptırmama gerek yoktu zaten her bilgisayar gerekli şeyleri gönderip bağlantısını kesiyordu. Ama ekran izlemede bunu beceremiyorum internet kafelerdeki sistemin uzak bilgisayar versiyonunu yapmak istiyorum yani

Karşı bilgisayarın ekranını izlemek için ekran görüntüsü-videosu alan bir kütüphane ile aldığınız medyayı UDP ile yollayabilirsiniz.

1 Beğeni