Reprinted: https://www.cnblogs.com/xiaowenshu/p/9916755.html
socket commonly referred to as "socket" is used to describe IP address and port, the communication link is a handle, the application issues a request to the network through the normally "sockets" network request or response.
socket originated in Unix, and one of the basic philosophy of Unix / Linux is the "everything is a file" to open the file [] [] [Close] to read and write mode operation. socket is a realization of the model, socket is a special file, some of them operating socket function is carried out (open, read / write IO, closed).
socket and file difference:
Files are all on the same computer, transferring data between two processes.
socket may be implemented in transmission of data between different computers, i.e. network traffic. For example, qq, open a web page, these are the socket to achieve communication.
Network communication but also that it comes tcp / ip udp protocol and protocol, socket which has a good package upd and tcp / ip protocols directly on it.
Simply under the tcp / ip protocol is doing, the network just came out, chaos, and that we all have to transfer data to comply with a rule, we all follow this, then appeared tcp / ip protocol. Maybe you heard of 3-way handshake, four times off, that is the process of a tcp / ip connection. Add a computer to computer communication and b, the process is such that
a: in it, I can not even you do
b: in, you even it
a: Well, I'm going to send you the data
# This is the 3-way handshake, which established a good channel, two computers can be passable again.
So what is it four times off
a: I want you off the
b: Well, you disconnect it
b: close the channel
a: closing the channel
Why off twice, because the data transfer ends to each other, we dug two paths, one path is used to transmit data to a b, b to the other one is a data transfer, it is turned off twice, each closing respective channels . The two roads it, there is a sub-called full-duplex, that is, both sides can send data to each other, if only one side can send data, it is called simplex.
FIG following, you can see the process of establishing the data connection and transmission process, and a disconnection process.
And the udp protocol is relatively simple, less complicated disconnection and connection, does not require 3-way handshake, the client does not need to determine whether the server can receive, tcp / ip must be established after a good connection to send data, and it is not udp connection, knowing ip and port number is directly sent, it is faster than tcp / ip, but unsafe.
upd like to write as possible on the road, there is no other party did not receive. The tcp / ip like to call, you must have turned to speak.
The following is udp server-side code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
import socket
'''
使用UDP协议时,不需要建立连接,只需要知道对方的IP地址和端口号,就可以直接发数据包。但是,能不能到达就不知道了。
虽然用UDP传输数据不可靠,但它的优点是和TCP比,速度快,对于不要求可靠到达的数据,就可以使用UDP协议。
我们来看看如何通过UDP协议传输数据。和TCP类似,使用UDP的通信双方也分为客户端和服务器。服务器首先需要绑定端口
绑定端口和TCP一样,但是不需要调用listen()方法,而是直接接收来自任何客户端的数据
'''
# ipv4 SOCK_DGRAM指定了这个Socket的类型是UDP
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定 客户端口和地址:
s.bind(('127.0.0.1', 9999))#绑定9999端口号
print('开始聊天了')
while True:
# 接收数据 自动阻塞 等待客户端请求:
data, addr = s.recvfrom(1024) #接收客户端发过来的数据和ip地址
data = data.decode()
print('客户端的ip信息',addr)
print('发过来的数据 %s'%data)
msg = input('你的回复:') #这个是咱们返回的数据
s.sendto(msg.encode(), addr)#把数据发送给客户端
# recvfrom()方法返回数据和客户端的地址与端口,这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发给客户端。
|
The following is a client-side code
1
2
3
4
5
6
7
8
9
10
11
12
|
import socket
'''
客户端使用UDP时,首先仍然创建基于UDP的Socket,然后不需要连接,直接通过sendto()给服务器发数据:
'''
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
data = input('data:')
s.sendto(data.encode(), ('127.0.0.1', 9999))#
# 发送数据:
recv = s.recv(1024) #返回的数据
print(recv.decode())
# 接收数据:
s.close()
|
Run the server-side code run client sends data to the server side, server-side back to the data and do a simple chat applet following results
Here is the code tcp / ip protocol, server-side code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import socket
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #建立一个tcp/ip scoket
sock.bind(('127.0.0.1',9999)) #绑定端口号
sock.listen(128)#监听,同时能连多少个客户端
while True:
print('开始等待下一个客户端过来。。。')
client,addr = sock.accept() #接收到客户端的socket,和地址
print('接收到 client数据',addr)
while True:
#
data = client.recv(1024)#获取到客户端的数据
data = data.decode()
if not data or data=='bye':
#如果没有发送过来数据就代表客户端close了,或者发过来bye代表连接要断开
print('服务结束',addr)
client.close()#断开连接,为下一个服务
break
else:#如果他还在发送的话
print('发过来的', data)
msg = input('回复:')
client.send(msg.encode()) # 数据
sock.close()
|
# The following is the client-side code connection service
1
2
3
4
5
6
7
8
9
10
11
12
|
import socket
s = socket.socket()
s.connect(('127.0.0.1',9999)) #连接服务端
while True:#
data = input('data:')
s.send(data.encode())#发送数据
recv = s.recv(1024).decode()
print(recv)
if data=='close':
break
s.close()
|
You might want to learn this dim it, in fact, these web frameworks underlying implementation is so, for example django, flask which will be a socket, we can also develop their own a web framework. Of course, now only a service to a client, with the multi-threaded or multi-process multiple clients that can be served.
The server runs the results
The following multi-threaded, every time a client came even started a thread to service, so that you can service multiple clients, start a thread by threading module to a request to start a thread for his service, as follows :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import socket,threading
class SocketServer:
def __init__(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 建立一个tcp/ip scoket
sock.bind(('127.0.0.1', 9999)) # 绑定端口号
sock.listen(128) # 监听
self.sock = sock
def start_server(self):
while True:
print('开始等待个客户端过来')
client,addr = self.sock.accept()
print('客户【%s】过来了',addr)
t = threading.Thread(target=self.client_recv,args=(client,addr))
t.start()
def client_recv(self,client,addr):
while True:
data = client.recv(1024) # 获取到客户端的数据
data = data.decode()
if not data or data == 'bye':
# 如果没有发送过来数据就代表客户端close了,或者发过来bye代表连接要断开
print('服务结束', addr)
client.close() # 断开连接,为下一个服务
break
else: # 如果他还在发送的话
print('发过来的', data)
msg = '统一回复,人不在'
client.send(msg.encode()) # 数据
if __name__ == '__main__':
t = SocketServer()
t.start_server()
|