socket编程

目录

Socket是什么

Socket中文翻译是套接字,它是应用层与TCP/IP协议族通信的中间软件抽象层,它所处的位置如下图所示:
Socket
它是一组接口,最初由加州伯克利分校的UNIX小组开发.在Unix一切皆文件哲学的思想下,它是一种”Open—read/Write—close”模式的实现,服务器和客户端各自维护一个”文件”,在建立连接打开后,可以向自己文件写入内容供对方读取或者读取对方内容,通讯结束时关闭文件。现在几乎所有流行的操作系统都支持它。QQ等网络应用都有它的身影,可以说在网络时代,一切都是Socket。

TCP Socket编程

TCP通信简介

TCP是一个面向连接的协议,这就意味着在客户和服务器能够开始正常通信之前,它们必须首先要握手和创建一个TCP连接。TCP连接的一端与客户套接字相联系,另一端与服务器套接字相联系。当创建TCP连接时,就将客户套接字地址(IP地址+端口号)和服务器套接字端口号(IP地址+端口号)关联起来,使用创建的TCP连接,当一侧要向另一侧发送数据时,它只需经过其套接字将数据丢给TCP连接。
那么TCP中客户端程序与服务器程序是如何交互的呢?
客户具有向服务器发起接触的任务。服务器为了能够对客户的初始接触做出响应,服务器必须已经准备好。这就意味着:一.TCP服务器程序必须在客户试图发起接触前作为进程运行起来。二.服务器程序必须有套接字来迎接任意主机上的客户端进程的初始接触。
随着服务器进程的运行,客户进程能够向服务器进程发起一个TCP连接,这是由客户程序通过创建一个TCP套接字来完成的。当客户生成其TCP套接字时,它指定了服务器创建的套接字的地址,即服务器主机的IP地址及其套接字的端口号。生成其套接字后,客户发起了一个三次握手并创建与服务器的一个TCP连接。
TCP三次握手过程如下图所示:
shangci

  • 第一次握手:客户端尝试连接服务器,向服务器发送syn包(同步序列编号Synchronize Sequence Numbers),syn=j,客户端进入SYN_SEND状态等待服务器确认
  • 第二次握手:服务器接收客户端syn包并确认(ack=j+1),同时向客户端发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态
  • 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手

TCP 通信过程如图:
tcp_socket

简单案例

实现功能

服务器接收来自客户端的消息然后发送回客户端并将其打印出来.

服务器

tcpserver.py

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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time, socket, threading
def tcplink(sock, addr):
print 'Accept new connection from %s:%s...' % addr
sock.send('Welcome!')
while True:
data = sock.recv(1024)
time.sleep(1)
if data == 'exit' or not data:
break
print '%s' % data
sock.send('Hello, %s!' % data)
sock.close()
print 'Connection from %s:%s closed.' % addr
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 监听端口:
s.bind(('xxx.xxx.xxx.xxx', 8000))
s.listen(5)
print 'Waiting for connection...'
while True:
# 接受一个新连接:
sock, addr = s.accept()
# 创建新线程来处理TCP连接:
t = threading.Thread(target=tcplink, args=(sock, addr))
t.start()

客户端

tcpclient.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接:
s.connect(('xxx.xxx.xxx.xxx', 8000))
# 接收欢迎消息:
print s.recv(1024)
for data in ['mindthink', 'code change the world', 'hello world']:
# 发送数据:
s.send(data)
print s.recv(1024)
s.send('exit')
s.close()

测试

客户端
kehudaun
服务器端
fuwuqiduan

打赏作者