zoukankan      html  css  js  c++  java
  • 套接字基础

    本文是续上文关于基于TCP套接字实现的简单Demo后进行套接字基本知识的讲解.


    可能文中有一些术语使用不太准确,但作为我自己的理解,尽量以通俗的语言为大家讲解.


    套接字即Socket.用于在进程之间进行通信.当然进程通信的方式多种多样,但是Socket在进程通信的使用却十分广泛.


    当然这里有几个概念需要区分.http,socket,tcp/ip之间的关系.大家都知道,现在互联网中广泛使用TCP/IP

    协议,如果你想要在当前的网络中传输数据,那么就必须遵守TCP/IP协议准则,而http是属于应用层面的协议,

    与FTP,Telnet等协议类似,当然还有用户自定义的一些协议.这些协议的目的是对TCP/IP传输的数据进行解

    析.而Socket作为进程通信的手段也是基于TCP/IP协议的,然而我们要实现应用层协议或者实现自己的协议,

    我们必须使用Socket提供的借口才能使这些协议数据是通过TCP/IP协议准则传输的.


    总之,TCP/IP是根本的准则.通过Socket我们才能利用TCP/IP协议.而应用层协议则提供我们对Socket传输的数

    据进行封包和解析的标准.


    对于一个套接字,我们可以看做是一条电话线路,而这条线路的建立则是基于TCP/IP标准的,而电话线两端就是我们

    通信的双方.


    那么一个套接字如何标识一个链接或者说如何识别通信的双方呢.


    那就是套接字三元组:    套接字=协议+端口+IP


    套接字分类:

    根据使用的协议类型不同,套接字分为三类.

    1.TCP套接字

    2.UDP套接字

    3.原始套接字.

    其中使用较为广泛的是TCP套接字和UDP套接字.而原始套接字是基于数据链路层协议.这里不作介绍.



    了解TCP协议都知道,TCP是面向链接的协议,在通信之前在通信双方要先进行“三次握手”成功建立连接

    后才能进行通信,所以其传输数据时可靠的,然而正是因为此原因,使得TCP的套接字传输效率要低一些.


    而UDP套接字是面向无连接,但是不提供可靠的数据传输.这点说明在传输的过程中有可能出现数据丢失,

    但是正是在传输之前不需要建议连接,这种数据传输的方式要高于TCP传输方式.


    原始套接字在这里也不作介绍,因为我也很少接触.



    阻塞与非阻塞:

    关于Socket字的方式 有两类

    1.阻塞方式

    2.非阻塞方式.


    我们可以简单的这样理解,阻塞方式是当建立多个套接字连接后,多个套接字同时传输和接受数据的

    方式可以成为非阻塞方式.而相反,当多个套接字进行连接后,只有只有当一个套接字完成接或者发数

    的方式后才能进行下一个套接字的收或者发数据的动作成为阻塞方式.显然阻塞方式要比非阻塞方

    式复杂.但是在实际应用中大多使用阻塞方式进行数据传输.阻塞方式大多使用多线程的方式实现.


    套接字地址结构:

    1 struct sockaddr_in
    2 {
    3 short sin_family;//AF_INET
    4 u_short sin_port;//16位端口号,网络字节顺序
    5 struct in_addr sin_addr;//32位IP地址,网络字节顺序
    6 char sin_zero[8];//保留
    7 }

    一个套接字地址结构就将套接字三元组完整的定义了.



    下面介绍TCP套接字的流程.流程图如下:




    不难看出我们可以对TCP套接字的服务器端和客户端用到的API进行总结:

    server:

    1.加载套接字库,进行套接字库初始化.这样我们才能使用需要的套接字.

    2.创建套接字:

    1 格式:SOCKET PASCAL FAR socket(int af,int type,int procotol);
    2 参数:af: 通信发生的区域
    3 type: 要建立的套接字类型
    4 procotol: 使用的特定协议

     

    3.初始化服务器端套接字地址

    1 SOCKADDR_IN addrSrv;
    2     addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    3     addrSrv.sin_family = AF_INET;
    4     addrSrv.sin_port = htons(6000)
    5 
    6 ;

    4.将套接字号和服务器端套接字进行绑定

    1 功能:将套接字地址与所创建的套接字号联系起来。格式:int PASCAL FAR bind(SOCKET s,const struct sockaddr FAR * name,int namelen);
    2 参数:s: 是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。
    3 其它:没有错误,bind()返回0,否则SOCKET_ERROR

    5.接受来自客户端的连接请求

    1 SOCKET PASCAL FAR accept(SOCKET s,struct sockaddr FAR * name,int FAR * addrlen);
    2 参数:同上

    6.数据发送和接受

    1 功能:数据的发送与接收
    2 格式:int PASCAL FAR send(SOCKET s,const char FAR * buf,int len,int flags);
    3 int PASCAL FAR recv(SOCKET s,const char FAR * buf,int len,int flags);
    4 参数:buf:指向存有传输数据的缓冲区的指针

    7.传输结束,关闭套接字

    1 关闭套接字――closesocket()
    2 功能:关闭套接字s
    3 格式:BOOL PASCAL FAR closesocket(SOCKET s);




    Client:

    1.建立客户端套接字同上

    2.将客户端套接字和服务器端地址接受绑定同上

    3.连接服务器

    1 int PASCAL FAR connect(SOCKET s,const struct sockaddr FAR * name,int namelen);

    4.进行数据发送和接受同上

    5.关闭套接字同上


    至此,关于Window套接字就介绍完了,虽然不尽详尽,但是我尽可能给大家讲清楚一些

    基本概念,和一些基本流程.在完全理解后,读者可以参照基于TCP套接字实现的简单Demo

    一文写一些自己的套接字小Demo.至于深入部分,只有靠大家自己了,我也是小鸟正在努力的.

  • 相关阅读:
    Ubuntu Server 17.04安装GNOME指令
    docker应用笔记
    无线网络连接配置
    bind9的一些配置
    关于linux下的文件权限
    命令行模式下设置时区
    Linux下SSL证书申请以及配置到Nginx
    编译安装Nginx到Linux
    网页画流程图
    为什么Java字符串是不可变对象?
  • 原文地址:https://www.cnblogs.com/vpoet/p/4659743.html
Copyright © 2011-2022 走看看