网络编程socket1

TCP/IP协议

  • IP协议负责把数据从一台计算机通过网络发送到另一台计算机。数据被分割成一小块一小块,然后通过IP包发送出去。由于互联网链路复杂,两台计算机之间经常有多条线路,因此,路由器就负责决定如何把一个IP包转发出去。IP包的特点是按块发送,途径多个路由,但不保证能到达,也不保证顺序到达。
  • TCP协议则是建立在IP协议之上的。TCP协议负责在两台计算机之间建立可靠连接,保证数据包按顺序到达。TCP协议会通过握手建立连接,然后,对每个IP包编号,确保对方按顺序收到,如果包丢掉了,就自动重发。
  • 许多常用的更高级的协议都是建立在TCP协议基础上的,比如用于浏览器的HTTP协议、发送邮件的SMTP协议等。
  • 一个TCP报文除了包含要传输的数据外,还包含源IP地址和目标IP地址,源端口和目标端口。
  • 端口有什么作用?
    • 在两台计算机通信时,只发IP地址是不够的,因为同一台计算机上跑着多个网络程序。一个TCP报文来了之后,到底是交给浏览器还是QQ,就需要端口号来区分。每个网络程序都向操作系统申请唯一的端口号,这样,两个进程在两台计算机之间建立网络连接就需要各自的IP地址和各自的端口号。
  • 一个进程也可能同时与多个计算机建立链接,因此它会申请很多端口。

 

Socket模块

一般来说建立服务器连接需要6步

  1. 创建socket对象,
  • socket.socket()
  1. 将socket绑定到指定地址上
  • socket.bind(address)
  1. 绑定后必须准备好套接字,一边接受连接请求
  • socket.listen(backlog), backlog用于指定最多连接数,至少为1
  1. 服务器套接字通过socket的accept方法等待客户请求一个连接
  • connection,address=socket.accept()
  • connection 指新的socket对象
  • address指客户网络地址
  1. 处理阶段,服务器和客户通过send和recv方法通信,传输数据
  2. 传输结束,服务器调用socket的close方法关闭连接

 

建立一个简单的客户连接需要4步

  1. 创建一个socket以连接服务器socket=socket.socket(family,type)
  2. 使用socket的connect方法连接服务器socket.connect((host,port))
  3. 客户和服务器通过send和recv方法通信
  4. 关闭客户端socket.close()

 

 

写一个客户端,和百度建立TCP连接,向其发送请求,把结果保存在baidu.html中

这是很多爬虫请求工具的底层原理

#!/usr/bin/env python3

# coding:utf-8



import socket

import codecs



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



host = 'www.baidu.com'



port = 80



s.connect((host,port))

# 向服务端发送请求

s.send(b'GET / HTTP/1.1\r\nHost:www.baidu.com\r\nConnection:close\r\n\r\n')

# 建立一个列表,储存收到的数据

buffer=[]



while 1:

# 每次接受1k字节的数据

    d = s.recv(1024)

    if d:

        buffer.append(d)

    else:
  
        break


# 把buffer列表里面接受到的数据拼接成data

data= b''.join(buffer)



header,html = data.split(b'\r\n\r\n',1)

print(header.decode("utf-8"))

with codecs.open('baidu.html','wb') as f:

    f.write(html)

s.close()

服务器端,写一个脚本等待连接,如果连上,并且接收到客户端发来的数据后,把数据返回给客户端

服务端脚本:

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# @date: 2018/6/1 上午9:57

# @author: Bill

# @file: server_socket.py



import socket

import threading

import time



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



host = socket.gethostname()



port = 9999



s.bind((host,port))



s.listen(5) # 设置最大的监听数



def tcp_link(sock, addr):

    print("Accept new connection from {}".format(addr))

    sock.send("欢迎使用tcp_link服务!".encode("utf-8"))

    while 1:

        data = sock.recv(1024)

        time.sleep(1)

        if not data or data.decode('utf-8') == "exit":

            break

        sock.send(("Receive data: %s" % data.decode("utf-8")).encode("utf-8"))

        # 注意上面一行的格式,要先把客户端接收到的数据解码,然后传到返回去的时候还要编码成utf-8

    sock.close()

    print("Connection closed from {}".format(addr))





while 1:

    sock,addr = s.accept()

    t = threading.Thread(target=tcp_link,args=(sock,addr))

    # 开启多线程,进行多个客户端的交互

    t.start()

 

客户端脚本

#!/usr/bin/env python

# -*- coding:utf-8 -*-

# @date: 2018/6/1 上午10:16

# @author: Bill

# @file: client.py



import socket

import time



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



host = socket.gethostname()

port = 9999



s.connect((host,port))



print(s.recv(1024).decode("utf-8"))



while 1:

    data = input("Please input the data you want to send: ")

        if data == "exit":

        break

    s.send(data.encode("utf-8"))

    d = s.recv(1024)

    time.sleep(1)

    print(d.decode("utf-8"))

 

 

 

 

 

 

 

转载于:https://my.oschina.net/u/3822958/blog/1822352

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值