zoukankan      html  css  js  c++  java
  • 如何正确理解套接字

    一、认识套接字

    TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket)或插口。
    套接字用(IP地址:端口号)表示。

    它是网络通信过程中端点的抽象表示,包含进行网络通信必需的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。

    套接字(socket)是一种通信机制,凭借这种机制,客户/服务器系统的开发工作既可以在本地单机上进行,也可以跨网络进行,Linux所提供的功能(如打印服 务,ftp等)通常都是通过套接字来进行通信的,套接字的创建和使用与管道是有区别的,因为套接字明确地将客户和服务器区分出来,套接字可以实现将多个客 户连接到一个服务器。

    但是说了半天,还是理解不了什么是套接字,其实这是一个狗屎一样的翻译问题:

    谷歌翻译中socket直译为插座,字典中关于socket的解释为:an electrical device receiving a plug or light bulb to make a connection。译为:接收插头或灯泡以进行连接的电气设备。用c/s模型图来更好的理解插座的意义:

    服务器就像一个大插排,包含很多插座,客户端就是像一个插头,每一个线程代表一条电线,客户端将电线的插头插到服务器插排上对应的插座上,就可以开始通信了。

    数据传输需要通过协议,而套接字就是给数据传输添加协议的。

    二、套接字特性

    1、套接字属性

    套接字的特性由3个属性确定,他们是,域,类型和协议

    域指定套接字通信中使用的网络介质,最常见的套接字域是AF_INET,它指的是Internet网络

    2、套接字类型

    一个套接字可能有多种不同的通信方式

    流套接字,流套接字提供一个有序,可靠,双向节流的链接,流套接字由类型SOCK_STREAM指定,它是在AF_INET域中通过TCP/IP链接实现的,这就是套接字类型(其实就是通信方式)

    与流套接字相反,由类型SOCK_DGRAM指定的数据报套接字不建立和维持一个连接,它对可以发送的数据长度有限制,数据报作为一个单独的网络消息被传输,它可能会丢失,复制或乱序

    3、套接字协议

    套接字协议,通常使用默认就可以了(也就是最后一个参数填0)

    三、基于套接字的TCP网络编程

    1、创建流程概述

    • socket创建一个套接字,SOCK_DGRAM是用在UDP上的,而SOCK_STREAM是用于TCP协议的。
    • bind绑定IP和port
    • listen使套接字变为可以被动链接
    • accept等待客户端的链接
    • close关闭资源

    2、socket模块常用于TCP的方法

    • connect(address):连接远程计算机
    • send():发送数据
    • recv():接收数据
    • listen:开始监听,等待客户端连接

    客户端实例:

    1.  
      from socket import *
    2.  
      #建立套接字,第二个参数是流式套接字 tcp专用
    3.  
      clientd_socket = socket(AF_INET,SOCK_STREAM)
    4.  
      #目标主机,也就是服务器的ip和端口
    5.  
      serverAddress = ('10.10.16.194',9999)
    6.  
      #主动和服务器发起链接
    7.  
      clientd_socket.connect(serverAddress)
    8.  
       
    9.  
      data = input('请输入数据')
    10.  
      #发送数据
    11.  
      clientd_socket.send(data.encode('utf-8'))
    12.  
      #接受数据
    13.  
      re = clientd_socket.recv(128)
    14.  
      print(re.decode('utf-8'))
    15.  
       
    16.  
      clientd_socket.close()
    • accept():响应客户端的请求

    阻塞当前线程

    如果没有计算机连接,一直等待

    如果有计算机连接,响应客户端

    服务端实例:

    1.  
      from socket import *
    2.  
      server_socket = socket(AF_INET,SOCK_STREAM)
    3.  
       
    4.  
      local_address = ('10.10.16.194',9999)
    5.  
      #绑定本机ip和端口,那么此程序就只接收此端口好的所有网络链接
    6.  
      server_socket.bind(local_address)
    7.  
       
    8.  
      #限制接受5个客户端的数据
    9.  
      server_socket.listen(5)
    10.  
      #接受链接,如果没有链接那么处于阻塞状态。
    11.  
      #有链接的时候,accept会返回两个值,第一个是socket链接,第二个是远程地址
    12.  
      lianjie,remoteAddress = server_socket.accept()
    13.  
      re = lianjie.recv(128)
    14.  
      print(re.decode('utf-8'))
    15.  
      #发送数据
    16.  
      data = input('请输入发送内容')
    17.  
      lianjie.send(data.encode('utf-8'))
    18.  
       
    19.  
      lianjie.close() #server_socket中的其中一个链接
    20.  
      server_socket.close() #server_socket相当于一个大的容器

    先运行服务端,在运行客户端:结果

    客户端:

    服务端:

    3、改进一下,让程序不会在一收一发后停止

    客户端:

    1.  
       
    2.  
      from socket import *
    3.  
      clientd_socket = socket(AF_INET,SOCK_STREAM)
    4.  
      serverAddress = ('10.10.16.194',9999)
    5.  
      clientd_socket.connect(serverAddress)
    6.  
      while True:
    7.  
      data = input('请输入数据')
    8.  
      clientd_socket.send(data.encode('utf-8'))
    9.  
      re = clientd_socket.recv(128)
    10.  
      print(re.decode('utf-8'))

    服务端:

    1.  
      from socket import *
    2.  
      server_socket = socket(AF_INET,SOCK_STREAM)
    3.  
      local_address = ('10.10.16.194',9999)
    4.  
      server_socket.bind(local_address)
    5.  
      server_socket.listen(5)
    6.  
      lianjie,remoteAddress = server_socket.accept()
    7.  
      while True:
    8.  
      re = lianjie.recv(128)
    9.  
      print(re.decode('utf-8'))
    10.  
      data = input('请输入发送内容')
    11.  
      lianjie.send(data.encode('utf-8'))
    12.  
      lianjie.close()
    13.  
      server_socket.close()
  • 相关阅读:
    SQL Server游标的使用【转】
    Window.Open参数、返回值
    .NET中class和struct的区别
    MVC中的几个问题汇总
    委托
    Hadoop集群环境搭建
    数学问题
    Ubuntu命令模式基础
    递归与分治-合并排序、快速排序以及循环赛问题
    Mongodb基础
  • 原文地址:https://www.cnblogs.com/zhj868/p/14188680.html
Copyright © 2011-2022 走看看