一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

linux中shell实现socket编程简单例子

时间:2015-06-29 编辑:简简单单 来源:一聚教程网

说到socket,学过网络基础的人都听过,他是TCP/IP的抽象,他是网络世界的入口,它无处不在。

学会了socket编程,就意味着能够更深层次的控制你的流量,之后再看python的urllib*或php的curl,简直就是小儿科!

I. 一些名词

Address Family

地址类型,协议族,可能是以下

socket.AF_INET ---> IPv4 addresses.
socket.AF_INET6 ---> IPv6 addresses.
socket.AF_UNIX ---> Unix domain sockets (例如 /var/run/mysqld/mysqld.sock is an example).
socket.AF_IPX ---> IPX addresses.
Socktype

sock类型

socket.SOCK_STREAM ---> 流式socket , for TCP
socket.SOCK_DGRAM ---> 数据报式socket , for UDP

其他

参数 取值 说明
Address Family AF_INET 2 IPv4
AF_INET6 23 IPv6
AF_UNSPEC 0 协议无关
Protocol Numbers 协议号 IPPROTO_IP 0 IP协议
IPPROTO_IPV4 4 IPv4
IPPROTO_IPV6 41 IPv6
IPPROTO_UDP 17 UDP
IPPROTO_TCP 6 TCP
Socktype sock类型 SOCK_STREAM 1
SOCK_DGRAM 2 数据报
ai_flags AI_PASSIVE 1 被动的,用于bind,通常用于server socket
AI_CANONNAME 2 用于返回主机的规范名称
  
AI_NUMERICHOST 4 地址为数字串


II. 简单的例子

来自官方文档的例子,很基础。

服务端

# Echo server program
import socket

HOST = '127.0.0.1'                 # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.sendall(data)
conn.close()
客户端

# Echo client program
import socket

HOST = 'localhost'    # The remote host
PORT = 50007              # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)


III. 更复杂的例子

服务端

与之前不同的是,支持IPV6

# Echo server program
import socket
import sys

HOST = None               # Symbolic name meaning all available interfaces
PORT = 50007              # Arbitrary non-privileged port
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
                              socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except socket.error as msg:
        s = None
        continue
    try:
        s.bind(sa)
        s.listen(1)
    except socket.error as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print 'could not open socket'
    sys.exit(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(1024)
    if not data: break
    conn.send(data)
conn.close()


客户端

# Echo client program
import socket
import sys

HOST = 'localhost'    # The remote host
PORT = 50007              # The same port as used by the server
s = None
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM):
    af, socktype, proto, canonname, sa = res
    try:
        s = socket.socket(af, socktype, proto)
    except socket.error as msg:
        s = None
        continue
    try:
        s.connect(sa)
    except socket.error as msg:
        s.close()
        s = None
        continue
    break
if s is None:
    print 'could not open socket'
    sys.exit(1)
s.sendall('Hello, world')
data = s.recv(1024)
s.close()
print 'Received', repr(data)

上面我们提到了socket编程的基本形式,这一节我们加强服务端的性能!

#!/usr/bin/env python

import socket, threading

class ClientThread(threading.Thread):

    def __init__(self, ip, port, socket):
        threading.Thread.__init__(self)
        self.ip = ip
        self.port = port
        self.socket = socket
        print "[+] New thread started for "+ip+":"+str(port)

    def run(self):   
        print "Connection from : "+ip+":"+str(port)

        self.socket.send("\nWelcome to the server\n\n")

        data = "dummydata"

        while len(data):
            data = self.socket.recv(2048)
            print "Client sent : "+data
            self.socket.send("You sent me : "+data)

        print "Client disconnected..."

host = "0.0.0.0"
port = 9999

tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

tcpsock.bind((host,port))
threads = []


while True:
    tcpsock.listen(4)
    print "\nListening for incoming connections..."
    (clientsock, (ip, port)) = tcpsock.accept()
    newthread = ClientThread(ip, port, clientsock)
    newthread.start()
    threads.append(newthread)

for t in threads:
    t.join()

热门栏目