奥门新浦京官方网站Python Socket 网络编程

本文由码农网 –
小峰原创翻译,转发请看清文末的转发供给,迎接参加我们的付费投稿安顿!

Socket
是经过间通讯的风姿浪漫种艺术,它与其它进程间通讯的二个首要差别是:它能促成不相同主机间的进度间通讯,大家网络上美妙绝伦的劳务好些个都是基于
Socket 来产生通讯的,譬喻我们每一天浏览网页、QQ 闲聊、收发 email
等等。要解决网络上两台主机之间的长河通信难点,首先要唯大器晚成标志该进程,在
TCP/IP 网络公约中,正是经过 (IP地址,左券,端口号)安慕希组来标记进程的,化解了经过标记难点,就有了通讯的底蕴了。

socket简介

套接字

介绍

Socket用于进程间通信。进度间通讯平时依照客商端—服务端模型。这时候,顾客端—服务端是足以相互相互的应用程序。客户端和服务端之间的并行须要连接。Socket编制程序负担的正是为应用程序之间确立可实行互相的连接。

在本文中,大家将学习怎么着用PHP成立一个总结的客商端—服务端。大家还将学习怎么样客商端应用程序怎么着发送消息到服务端,以致哪些从服务端选择音信。

奥门新浦京官方网站 1

正文首要介绍使用 Python 实行 TCP Socket
网络编制程序,假若你早就具备初始的互连网文化及 Python 基本语法知识。

1.地面包车型客车长河间通讯(IPC)有很各类办法,例如

• 队列
• 同步(互斥锁、条件变量等)
如上通信方式都以在风姿洒脱台机器上区别进度之间的通讯格局,那么难题来了
互联网中经过之间怎么通讯?

运用代码

指标:开垦三个顾客端用于发送string消息到服务端,服务端将同样的新闻反转后归来给顾客端。

PHP服务器

第1步:设置变量,如“主机”和“端口”

$host = "127.0.0.1";
$port = 5353;
// No Timeout 
set_time_limit(0);

端口号能够是1024 -65535之间的其余正整数。

第2步:创建socket

$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socketn");

第3步:绑定socket到端口和主机

创立的socket财富绑定到IP地址和端口号。

$result = socket_bind($socket, $host, $port) or die("Could not bind to socketn");

第4步:启动socket监听

在绑定到IP和端口后,服务端早前等待顾客端的连年。在并未有连接以前它就直接等下去。

$result = socket_listen($socket, 3) or die("Could not set up socket listenern");

第5步:选择连接

这么些函数会采用所建的socket传入的总是必要。在承担来自顾客端socket的接连后,该函数重临另一个socket能源,实际上正是负担与相应的客商端socket通信。这里的“$spawn”正是背负与顾客端socket通讯的socket能源。

$spawn = socket_accept($socket) or die("Could not accept incoming connectionn");

到将来终止,大家早已筹划好了劳务端socket ,但实际上这么些剧本并未做别的业务。所认为了世襲产生上述指标,大家将读取顾客端socket新闻,然后将收到到的消息反转后发回给客商端socket。

第6步:从客户端socket读取音讯

$input = socket_read($spawn, 1024) or die("Could not read inputn");

第7步:反转音信

$output = strrev($input) . "n";

第8步:发送信息给顾客端socket

socket_write($spawn, $output, strlen ($output)) or die("Could not write outputn");

关闭socket

socket_close($spawn);
socket_close($socket);

那就完事了服务端。以往,我们上学如何成立PHP顾客端。

PHP客户端

前七个步骤与服务端相似。

第1步:设置变量,如“主机”和“端口”

$host = "127.0.0.1";
$port = 5353;
// No Timeout 
set_time_limit(0);

奥门新浦京官方网站,注:这里的端口和主机应该和服务端中的定义是同样的。

第2步:创建socket

$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socketn");

第3步:连接到服务端

$result = socket_connect($socket, $host, $port) or die("Could not connect toservern");

那个时候和服务端差别,顾客端socket不绑定端口和主机。相反,它连接到劳动端socket,等待接纳来自客商端socket的连接。这一步组建了客商端socket到劳动端socket的延续。

第4步:写入服务端socket

socket_write($socket, $message, strlen($message)) or die("Could not send data to servern");

在这里步骤中,顾客端socket的数目被发送到服务端socket。

第5步:阅读来自服务端的响应

$result = socket_read ($socket, 1024) or die("Could not read server responsen");
echo "Reply From Server  :".$result;

第6步:关闭socket

socket_close($socket);

全体的代码

服务端(server.php)

// set some variables
$host = "127.0.0.1";
$port = 25003;
// don't timeout!
set_time_limit(0);
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socketn");
// bind socket to port
$result = socket_bind($socket, $host, $port) or die("Could not bind to socketn");
// start listening for connections
$result = socket_listen($socket, 3) or die("Could not set up socket listenern");

// accept incoming connections
// spawn another socket to handle communication
$spawn = socket_accept($socket) or die("Could not accept incoming connectionn");
// read client input
$input = socket_read($spawn, 1024) or die("Could not read inputn");
// clean up input string
$input = trim($input);
echo "Client Message : ".$input;
// reverse client input and send back
$output = strrev($input) . "n";
socket_write($spawn, $output, strlen ($output)) or die("Could not write outputn");
// close sockets
socket_close($spawn);
socket_close($socket);

客户端(client.php)

$host    = "127.0.0.1";
$port    = 25003;
$message = "Hello Server";
echo "Message To server :".$message;
// create socket
$socket = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socketn");
// connect to server
$result = socket_connect($socket, $host, $port) or die("Could not connect to servern");  
// send string to server
socket_write($socket, $message, strlen($message)) or die("Could not send data to servern");
// get server response
$result = socket_read ($socket, 1024) or die("Could not read server responsen");
echo "Reply From Server  :".$result;
// close socket
socket_close($socket);

确立上述文件(server.php和client.php)后,实施如下操作:

  1. 复制www目录中的那几个文件(假若WAMP),安放于C:wamp。
  2. 开拓Web浏览器,在地方栏中键入localhost 。
  3. 先浏览server.php然后client.php。

TCP 是少年老成种面向连接的传输层左券,TCP Socket 是依据风度翩翩种 Client-Server
的编制程序模型,服务端监听顾客端的连接央浼,生机勃勃旦确立连接即能够展开传输数据。那么对
TCP Socket 编制程序的牵线也分为顾客端和服务端:

2. 互联网中经过之间什么通讯

驷不如舌消除的标题是怎么唯蓬蓬勃勃标记二个历程,不然通讯无从谈起!
在本地能够因此进程PID来唯生龙活虎标记一个历程,可是在互联网中这是无用的。
实际上TCP/IP公约族已经帮大家减轻了这几个主题材料,互连网层的“ip地址”能够唯大器晚成标志网络中的主机,而传输层的“合同+端口”能够唯意气风发标记主机中的应用程序(进程)。
像这种类型利用ip地址,公约,端口就能够标志互连网的进程了,网络中的进度通信就足以动用这几个标记与其他进度展开交互作用

许可证

这篇文章,甚至其余相关的源代码和文书,是由此The Code Project Open
License (CPOLState of Qatar许可的。

顾客端编制程序

3. 什么是socket

socket(简称 套接字)是经过间通讯的生机勃勃种办法,它与任何进度间通讯的一个主要分歧是:
它能落到实处不一致主机间的历程间通讯,我们网络上各式各样标劳务超级多都以依据Socket 来完成通讯的
诸如我们天天浏览网页、QQ 聊天、收发 email 等等

  1. 创建socket
    在 Python 中 使用socket 模块的函数 socket 就足以做到:
    socket.socket(AddressFamily, Type)
    说明:
    函数 socket.socket 创设二个 socket,重临该 socket
    的描述符,该函数带有多少个参数:
    • Address Family:能够接纳 AF_INET(用于 Internet 进度间通讯) 大概AF_UNIX(用于同生机勃勃台机器进度间通讯),实际专门的学业中常用AF_INET
    • Type:套接字类型,能够是 SOCK_STREAM(流式套接字,首要用以 TCP
    合同)只怕 SOCK_DGRAM(数据报套接字,重要用以 UDP 协议)
    制造四个tcp socket(tcp套接字)
    import socket
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print ‘Socket Created’

创建 socket

第生龙活虎要创立 socket,用 Python 中 socket 模块的函数 socket 就足以成功:

#Socket client example in python

import socket   #for sockets

#create an AF_INET, STREAM socket (TCP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

print 'Socket Created'

函数 socket.socket 创设多个 socket,再次回到该 socket
的描述符,将要前边相关函数中应用。该函数带有三个参数:

  • Address Family:能够选用 AF_INET(用于 Internet 进度间通讯) 或然
    AF_UNIX(用于同大器晚成台机械进度间通讯)
  • Type:套接字类型,能够是 SOCKET_STREAM(流式套接字,首要用于 TCP
    左券)只怕 SOCKET_DGRAM(数据报套接字,首要用于 UDP 合同)

注:由于本文首要概述一下 Python Socket
编制程序的过程,因而不会对相关函数参数、再次来到值进行详细介绍,须求理解的可以查占星关手册

错误处理

万黄金年代成立 socket 函数战败,会抛出叁个 socket.error 的丰裕,须要捕获:

#handling errors in python socket programs

import socket   #for sockets
import sys  #for exit

try:
    #create an AF_INET, STREAM socket (TCP)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
    print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
    sys.exit();

print 'Socket Created'

那么到近些日子截至已成功创立了 socket,接下去大家将用那个 socket
来连接有个别服务器,就连
www.google.com 吧。

成立一个udp socket(udp套接字)
   import socket

    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    print 'Socket Created'

三回九转服务器

本文最早也涉嫌了,socket 使用 (IP地址,左券,端口号卡塔尔国来标记叁个经过,那么大家要想和服务器实行通信,就须要知道它的
IP地址以致端口号。

获得远程主机的 IP 地址

Python 提供了四个简易的函数 socket.gethostbyname 来得到远程主机的 IP
地址:

host = 'www.google.com'
port = 80

try:
    remote_ip = socket.gethostbyname( host )

except socket.gaierror:
    #could not resolve
    print 'Hostname could not be resolved. Exiting'
    sys.exit()

print 'Ip address of ' + host + ' is ' + remote_ip

目前大家精晓了服务器的 IP 地址,就足以选择连接函数 connect 连接到该 IP
的有个别特定的端口上了,下边例子连接到 80 端口上(是 HTTP
服务的私下认可端口):

#Connect to remote server
s.connect((remote_ip , port))

print 'Socket Connected to ' + host + ' on ip ' + remote_ip

运转该程序:

$ python client.py
Socket created
Ip of remote host www.google.com is 173.194.38.145
Socket Connected to www.google.com on ip 173.194.38.145

UDP介绍

UDP —
顾客数据报公约,是三个无连接的简短的面向数据报的运输层公约。UDP不提供可信赖性,它只是把应用程序传给IP层的数量报发送出去,不过并无法保险它们能达到目标地。由于UDP在传输数据报前不用在客商和服务器之间建构一个连连,且未有过期重发等体制,故而传输速度极快。
UDP是一种面向无连接的磋商,每种数据报都以贰个独门的消息,包涵总体的源地址或指标地址,它在互联网上以其它大概的门路传往目标地,由此能或不能够达到指标地,到达指标地的时光以致内容的不错都以不能被保障的。

发送数据

地方表明连接到
www.google.com
已经成功了,接上面大家得以向服务器发送一些数据,举例发送字符串
GET / HTTP/1.1rnrn,那是七个 HTTP 央浼网页内容的一声令下。

#Send some data to remote server
message = "GET / HTTP/1.1rnrn"

try :
    #Set the whole string
    s.sendall(message)
except socket.error:
    #Send failed
    print 'Send failed'
    sys.exit()

print 'Message send successfully'

发送完数据之后,客商端还要求接纳服务器的响应。

UDP特点:

UDP是面向无连接的简报协议,UDP数据富含指标端口号和源端口号音讯,由于通信没有必要三番五回,所以能够达成广播发送。
UDP传输数据时有大小节制,每种被传输的多寡报必得界定在64KB之内。
UDP是一个离谱赖的商量,发送方所发送的数量报并不一定以相仿的主次到达采用方。

选拔数据

函数 recv 能够用来接过 socket 的数据:

#Now receive data
reply = s.recv(4096)

print reply

联机械运输维的结果如下:

Socket created
Ip of remote host www.google.com is 173.194.38.145
Socket Connected to www.google.com on ip 173.194.38.145
Message send successfully
HTTP/1.1 302 Found
Cache-Control: private
Content-Type: text/html; charset=UTF-8
Location: http://www.google.com.sg/?gfe_rd=cr&ei=PlqJVLCREovW8gfF0oG4CQ
Content-Length: 262
Date: Thu, 11 Dec 2014 08:47:58 GMT
Server: GFE/2.0
Alternate-Protocol: 80:quic,p=0.02

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>302 Moved</TITLE></HEAD><BODY>
<H1>302 Moved</H1>
The document has moved
<A HREF="http://www.google.com.sg/?gfe_rd=cr&ei=PlqJVLCREovW8gfF0oG4CQ">here</A>.
</BODY></HTML>
【适用境况】

UDP是面向新闻的磋商,通讯时无需建构连接,数据的传输自然是离谱的,UDP日常用来多点通讯和实时的数据业务,举个例子
• 语音广播
• 视频
• QQ
• TFTP(轻巧文件传送)
• SNMP(简单互联网管理合同)
• 福睿斯IP(路由消息公约,如告诉股市,航空消息)
• DNS(域名解释)

关闭 socket

当大家不想再一次央浼服务器数据时,能够将该 socket 关闭,甘休本次通讯:

s.close()
强调速度流畅

UDP操作轻易,而且仅供给少之甚少的监护,因而普通用于局域网高可信性的分散系统中client/server应用程序。举个例子录制会议系统,并不供给音频录像数据绝没错科学,只要有限协理连贯性就足以了,这种境况下鲜明使用UDP会更合理一些。

小结

上边我们学到了怎么:

  1. 创建 socket
  2. 连年到长途服务器
  3. 发送数据
  4. 接纳数据
  5. 关闭 socket

当大家开采
www.google.com
时,浏览器所做的就是那个,知道这几个是丰盛有意义的。在 socket
中存有这种行为特征的被称得上CLIENT,客户端首固然接连远程系统获取数据。

socket 中另后生可畏种表现称作SERVER,服务器使用 socket
来接收三番若干回以及提供数据,和顾客端刚刚相反。所以
www.google.com
是服务器,你的浏览器是客商端,可能越来越纯粹地说,www.google.com
是 HTTP 服务器,你的浏览器是 HTTP 客商端。

那么地点介绍了顾客端的编制程序,以后轮到服务器端如若接收 socket 了。

udp网络程序-发送数据

socket函数
mySocket = socket(family, type)

函数socket(卡塔尔的参数family用于安装网络通信的域,函数socket(卡塔尔根据那个参数采取通讯左券的族。通讯左券族在文书sys/socket.h中定义。

奥门新浦京官方网站 2

Paste_Image.png

函数socket(卡塔尔国的参数type用于安装套接字通讯的种类,主要有SOCKET_STREAM(流式套接字)、SOCK——DGRAM(数据包套接字)等。
并非独具的合同族都实现了这个左券项目,举个例子,AF_INET左券族就不曾兑现SOCK_SEQPACKET左券项目。

奥门新浦京官方网站 3

Paste_Image.png

创办三个udp顾客端程序的流水生产线是简单,具体步骤如下:

  1. 创设客商端套接字
  2. 发送/选用数据
  3. 关闭套接字

      from socket import *
  1. 创设套接字
    udpSocket = socket(AF_INET, SOCK_DGRAM)
  2. 绸缪接纳方的地址
    sendAddr = (‘192.168.11.74’, 7788)
  3. 从键盘获取数据
    sendData = input(“请输入要发送的多少:”State of Qatar
  4. 发送数据到钦赐的Computer上
    udpSocket.sendto(sendData.encode(‘gbk’), sendAddr)
  5. 关闭套接字
    udpSocket.close()

劳务器端编制程序

服务器端首要做以下职业:

  • 打开 socket
  • 绑定到特定的地址以至端口上
  • 监听连接
  • 建构连接
  • 吸收/发送数据

上面已经介绍了怎么创建 socket 了,上边一步是绑定。

udp 互联网程序-端口难题

奥门新浦京官方网站 4

Paste_Image.png

说明:

每重国民党的新生活运动行一回网络程序,上海体育场所中红圈中的数字,不相近的来由在于,那个数字标志这些网络程序,当再一次运营时,若无明确到底用哪些,系统暗中认可会轻便分配

记住一点:这一个互连网程序在运营的长河中,这些就唯意气风发标记这么些程序,所以只要其它Computer上的网络程序意气风发旦想要向此程序发送数据,那么就须要向那一个数字(即端口)标志的主次发送就能够

绑定 socket

函数 bind 能够用来将 socket 绑定到特定的地址和端口上,它须求一个
sockaddr_in 结构作为参数:

import socket
import sys

HOST = ''   # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

try:
    s.bind((HOST, PORT))
except socket.error , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()

print 'Socket bind complete'

绑定完结之后,接下去正是监听连接了。

udp绑定音信

日常情状下,在一天Computer上运营的互连网程序有过多,而个别用的端口号比超级多动静下不亮堂,为了不与别的的网络程序占用同三个端口号,往往在编制程序中,udp的端口号平日不绑定
唯独若是供给做成三个服务器端的次第的话,是急需绑定的,出主意看这又是怎么吧?
设若报告急察方电话天天都在变,想必世界就能够乱了,所以日平常服装务性的次第,往往要求一个长久的端口号,那就是所谓的端口绑定

监听连接

函数 listen 能够将 socket 置于监听格局:

s.listen(10)
print 'Socket now listening'

该函数带有叁个参数称为 backlog,用来决定连接的个数。假设设为
10,那么有 10 个三番若干回正在等待管理,那时候第 11 个央求过来时将会被谢绝。

绑定示例
    #coding=utf-8

    from socket import *

    #1. 创建套接字
    udpSocket = socket(AF_INET, SOCK_DGRAM)

    2. 绑定本地的相关信息,如果一个网络程序不绑定,则系统会随机分配
    bindAddr = ('', 7788) # ip地址和端口号,ip一般不用写,表示本机的任何一个ip
    udpSocket.bind(bindAddr)

    #3. 等待接收对方发送的数据
    recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最大字节数

    #4. 显示接收到的数据
    print(recvData)

    #5. 关闭套接字
    udpSocket.close()

总结

三个udp网络程序,能够不绑定,那个时候操作系统会自由开展分红二个端口,借使重复运维次程序端口大概会发生变化

多少个udp互连网程序,也得以绑定音讯(ip地址,端口号),假诺绑定成功,那么操作系统用这么些端口号来展开区分收到的互连网数据是或不是是此进程的

收纳一而再

当有客商端向服务器发送连接乞求时,服务器会选择三番五次:

#wait to accept a connection - blocking call
conn, addr = s.accept()

#display client information
print 'Connected with ' + addr[0] + ':' + str(addr[1])

运作该程序的,输出结果如下:

$ python server.py
Socket created
Socket bind complete
Socket now listening

当时,该程序在 8888
端口上等待乞请的过来。不要关掉那些程序,让它一向运维,今后顾客端能够经过该端口连接到
socket。大家用 telnet 顾客带给测验,张开一个极限,输入
telnet localhost 8888

$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Connection closed by foreign host.

那个时候服务端输出会呈现:

$ python server.py
Socket created
Socket bind complete
Socket now listening
Connected with 127.0.0.1:59954

笔者们观见到客商端已经延续上服务器了。在创制连接之后,大家能够用来与顾客端实行通讯。上面例子演示的是,服务器创设连接之后,选拔客户端发送来的数据,并及时将数据发送回去,上面是完整的服务端程序:

import socket
import sys

HOST = ''   # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

try:
    s.bind((HOST, PORT))
except socket.error , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()

print 'Socket bind complete'

s.listen(10)
print 'Socket now listening'

#wait to accept a connection - blocking call
conn, addr = s.accept()

print 'Connected with ' + addr[0] + ':' + str(addr[1])

#now keep talking with the client
data = conn.recv(1024)
conn.sendall(data)

conn.close()
s.close()

在一个终极中运转这一个程序,展开另叁个终端,使用 telnet
连接服务器,随意输入字符串,你探望到:

$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
happy
happy
Connection closed by foreign host.

客商端(telnet)选拔了服务器的响应。

大家在落成一回响应之后服务器立刻断开了一连,而像
www.google.com
那样的服务器总是向来守候接纳延续的。大家须要将方面包车型地铁服务器程序改形成一贯运维,最轻巧易行的艺术是将
accept 放到多少个周而复始中,那么就足以大器晚成间接选举用延续了。

udp广播

TCP/IP合同栈中, 传输层唯有UDP能够广播.

奥门新浦京官方网站 5

Paste_Image.png

维持服务

咱俩得以将代码改成那样让服务器平昔职业:

import socket
import sys

HOST = ''   # Symbolic name meaning all available interfaces
PORT = 5000 # Arbitrary non-privileged port

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

try:
    s.bind((HOST, PORT))
except socket.error , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()

print 'Socket bind complete'

s.listen(10)
print 'Socket now listening'

#now keep talking with the client
while 1:
    #wait to accept a connection - blocking call
    conn, addr = s.accept()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])

    data = conn.recv(1024)
    reply = 'OK...' + data
    if not data: 
        break

    conn.sendall(reply)

conn.close()
s.close()

现行反革命在一个极限下运作方面包车型大巴服务器程序,再展开三个极端,分别用 telnet
去老是,假使三个终极连接之后不输入数据其余终端是不能进行连接的,何况每一种终端只能服务贰次就断开连接。那从代码上也是能够看出来的。

那显著亦非我们想要的,大家希望八个客商端能够天天创立连接,而且各种顾客端能够跟服务器实行数十次通讯,那该怎么更改呢?

udp总结

  1. udp是TCP/IP公约族中的黄金年代种公约可以成功差别机器上的次第间的数目通讯
  2. udp服务器、客户端

    udp的服务器和顾客端的界别:往往是通过乞请服务和提供劳动来展开区分
    • 诉求服务的一方称为:客商端
    • 提供劳动的一方称为:服务器
  3. udp绑定难点

    日常景观下,服务器端,必要绑定端口,指标是为着让其余的顾客端能够准确发送到此进度

    客商端,平日没有必要绑定,而是让操作系统随机分配,那样就不会因为须求绑定的端口被挤占而变成程序不或者运营的情事

拍卖连接

为了管理每一个连接,我们必要将管理的顺序与主程序的收纳三番三遍分开。黄金年代种方法能够使用线程来贯彻,主服务程序选取三番若干回,成立一个线程来拍卖该连接的通讯,然后服务器回到选用其他总是的逻辑上来。

import socket
import sys
from thread import *

HOST = ''   # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'

#Bind socket to local host and port
try:
    s.bind((HOST, PORT))
except socket.error , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()

print 'Socket bind complete'

#Start listening on socket
s.listen(10)
print 'Socket now listening'

#Function for handling connections. This will be used to create threads
def clientthread(conn):
    #Sending message to connected client
    conn.send('Welcome to the server. Type something and hit entern') #send only takes string

    #infinite loop so that function do not terminate and thread do not end.
    while True:

        #Receiving from client
        data = conn.recv(1024)
        reply = 'OK...' + data
        if not data: 
            break

        conn.sendall(reply)

    #came out of loop
    conn.close()

#now keep talking with the client
while 1:
    #wait to accept a connection - blocking call
    conn, addr = s.accept()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])

    #start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
    start_new_thread(clientthread ,(conn,))

s.close()

再次运转方面包车型地铁次第,展开三个极点来与主服务器创设 telnet
连接,当时多少个客商端能够每天接入,何况各种客商端能够与主服务器进行频仍通讯。

telnet 终端下只怕输出如下:

$ telnet localhost 8888
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Welcome to the server. Type something and hit enter
hi
OK...hi
asd
OK...asd
cv
OK...cv

要结束 telnet 的连接,按下 Ctrl-] 键,再输入 close 命令。

服务器终端的输出恐怕是那般的:

$ python server.py
Socket created
Socket bind complete
Socket now listening
Connected with 127.0.0.1:60730
Connected with 127.0.0.1:60731

udp综合营业-模拟QQ

任务须要:
• 使用八十一线程实现叁个全双工的QQ闲聊程序
单工、半双工、全双工
单工数据传输只帮忙数据在八个主旋律上传输;
半双工数据传输允许数据在五个样子上传输,不过,在某不常刻,只同意数据在叁个大方向上传输,它实质上是生机勃勃种切换方向的单工通讯;
全双工数据通讯允许数据同不时候在三个方向上传输,因而,全双工通讯是两个单工通讯方式的构成,它需求发送设备和选拔设备都有单独的收纳和发送手艺.

总结

到近日停止,大家学习了 Python 下基本的 socket 编制程序。

参谋资料

  • 关键译自: Python socket – network programming
    tutorial
  • 越是读书:
    • Sockets programming in
      Python
    • Python socket – chat server and client with code
      example
    • Linux
      Socket编程(不限Linux)

发表评论

电子邮件地址不会被公开。 必填项已用*标注