Port Nedir? Bir network cihazından diğerine veri gönderilirken hedef cihazın bu veri ile ilgili ne yapacağına dair bir bilgi göndermeye bir yol sağlanmamıştır. TCP ve UDP bu soruna port adı verilen bir çözüm sağlar. Port network cihazı üzerinde atanan IP adreslerine bağlı bir uç noktadır. Portlar, network cihazı üzerindeki çalışan processler tarafından sahiplenilir ve process bu portu dinlediğini söyler. Portlar 16 bitlik sayılar halinde gösterilir. Bu da bir cihaz üzerindeki IP adresinin processlerin sahiplenebileceği 65535 olası port numarasına sahip olduğunu gösterir. Bir port aynı anda bir process tarafından dinlenebilir. Fakat bir process birden fazla portu dinleyebilir. Her uygulama port numarasını belirtmek zorundadır. Eğer belirtmezse işletim sistemi tarafondan otomatik olarak atanır. Network Socket Nedir? İnterface adresi ile port numarasının birleşimi socket olarak adlandırılır. Bir network socket, varlıkların işlemler arası iletişimi gerçekleştirebileceği sanal bir uç noktadır. Bir başka deyişle socketi evimizin kapısı gibi düşünebiliriz. Evimizden(Bilgisayar) dışarıya(network) çıkmak isteyen birisi bu kapılardan geçmek zorundadadır. Örneğin; web programları 80. portu, FTP programları 21. portu kullanan soket programlarıdır. İstemci process görevini tamamladıktan sonra bağlantıyı kapatarak ayrılır. Fakat server process hala o portu dinlemektedir. Başarılı bir socket bind işleminden sonra, sunucu process gelecek istemci bağlantısını dinlemeye başlar. Geçerli bir istemci oturumu için, sunucu process istemci process in isteğini kabul edebilir. Bu noktada, sunucu ile istemci arasında bağlatı kuruldu denilebilir. Daha sonra, istemci/sunucu istek/yanıt döngüsüne girer. İstemci process sunucu process e veri gönderir, sunucu process verileri işler ve istemciye cevap gönderir. İstemci process işini bitirdiğinde, bağlantıyı kapatarak çıkar. Bu noktada, server process dinleme durumundadır. Pratikte, bir server process i ilgili sanal kanallar üzerinden gelen binlerce müşteriden gelen eş zamanlı bağlantıları işlemek için birden çok thread ve subprocess ler içerir. Python socket Library s=socket.socket(family, type, protocol) family: AF_INET: Bu adres ailesi bir (host, port) çiftinden oluşmaktadır. Buradaki host domain adresi olabileceği gibi IPv4 adresi de olabilir. AF-INET6: Bu aile (host, port, flowinfo, scopeid) şeklinde bir tuple şeklinde kullanılır. flowinfo ve scopeid C deki scokaddr struct ındaki sin6_flowinfo ve sin6_scope_id üyelerini temsil eder. AF_BLUETOOTH: Bluetooth üzerinden işlem yapmaya yarar. Bunların dılında AF_UNIX, AF_CAN, AF_NETLINK, AF_ALG gibi parametreler de mevcuttur. type: Genelde UDP için SOCK_DGRAM, TCP için SOCK_STREAM kullanılır.
protocol: default değeri 0 dır. o anda kullanılan hostun ismini öğrenmek için; print(socket.gethostname()) kullanılır. Bir domainin ip adresini kullanmak için gethostbyname kullanılır. for host in ["burakkiymaz.com", "www.python.org","burak"]: print("%15s : %s"%(host, socket.gethostbyname(host))) print("%15s : ERROR : %s"%(host, error.args[1])) burakkiymaz.com : 104.18.45.59 www.python.org : 151.101.112.223 burak : ERROR : Name or service not known Daha fazla bilgiye erişmek için gethostbyname_ex kullanılır. for host in ["burakkiymaz.com", "www.python.org","burak"]: print(host) hostname, aliases, addresses = socket.gethostbyname_ex(host) print("hostname: ", hostname) print("aliases: ", aliases) print("adresses: ", addresses) print("%15s : ERROR : %s"%(host, error.args[1])) print() burakkiymaz.com Hostname: burakkiymaz.com Aliases: [] Adresses: ['104.18.45.59', '104.18.44.59'] www.python.org Hostname: python.map.fastly.net Aliases: ['www.python.org'] Adresses: ['151.101.112.223'] burak burak : ERROR : Name or service not known Eğer sunucunun IP adresi biliniyorsa ip adresi üzerinden tarama yapmak için gethostbyaddr kullanılır. İlgili servisin hangi portta hizmet verdiği hakkında bilgi almak için getservbyname kullanılır.
import urllib.parse for url in [ 'http://burakkiymaz.com', 'https://www.mybank.com', 'ftp://prep.ai.mit.edu', 'gopher://gopher.micro.umn.edu', 'smtp://mail.sdu.edu.tr', 'imap://mail.example.com' ]: parsed_url = urllib.parse.urlparse(url) port = socket.getservbyname(parsed_url.scheme) print("%6s : %s" %(parsed_url.scheme, port)) http : 80 https : 443 ftp : 21 gopher : 70 smtp : 25 imap : 143 Verilen adresle ilgili bilgi edinmek için getaddrinfo kullanılır. def get_constants(prefix): return dict( (getattr(socket, n), n) for n in dir(socket) if n.startswith(prefix) ) families = get_constants('af_') types = get_constants('sock_') protocols = get_constants('ipproto_') for response in socket.getaddrinfo('burakkiymaz.com', 'http'): family, socktype, proto, canonname, sockaddr = response print('family: : ', families[family]) print('type : ', types[socktype]) print('protocol : ', protocols[proto]) print('canonical name : ', canonname) print('socket Address : ', sockaddr) Family: : AF_INET Type : SOCK_STREAM Protocol : IPPROTO_TCP Canonical name : socket Address : ('104.18.44.59', 80) Bir Client üzerinden server sockete bağlanma import sys
sock = socket.socket(socket.af_inet, socket.sock_stream) print('socket oluşturulamadı') print('reason: ',error) sys.exit() print('socket oluşturuldu.') hedef_sunucu = input("bağlanmak istediğiniz sunucuyu giriniz: ") hedef_port = input("hedef port numarasını giriniz: ") sock.connect((hedef_sunucu, int(hedef_port))) print("socket %s üzerindeki %s portuna bağlandı"%(hedef_sunucu, hedef_port)) sock.shutdown(2) print("socket %s üzerindeki %s portuna bağlanamadı") print("sebep: ",error) sys.exit() socket oluşturuldu. Bağnamka istediğiniz sunucuyu giriniz: burakkiymaz.com Hedef port numarasını giriniz: 80 Socket burakkiymaz.com üzerindeki 80 portuna bağlandı Veri gönderip alan bir TCP socket client oluşturma HOST = "www.linux.org" PORT = 80 BUFFER_SIZE = 4096 ADDR = (HOST, PORT) client_sock = socket.socket(socket.af_inet, socket.sock_stream) client_sock.connect(addr) while True: data = 'GET / HTTP/1.0\r\n\r\n' if not data: break client_sock.send(data.encode('utf-8')) data = client_sock.recv(buffer_size) if not data: break print(data.decode('utf-8')) client_sock.close()
HTTP/1.1 200 OK Date: Wed, 22 Feb 2017 11:40:32 GMT Server: Apache Last-Modified: Mon, 25 Jul 2016 13:28:43 GMT Accept-Ranges: bytes Content-Length: 111 Connection: close Content-Type: text/html <html><head><meta HTTP-EQUIV="refresh" CONTENT="0;URL=/cgi-sys/defaultwebpage.cgi"></head><body></body></html>