套接字

1.什么是套接字?

  套接字(socket)是一种通信机制,凭借这种机制,客户/服务器系统的开发工作既可以在本地单机上进行,也可以跨网络进行。

2.套接字应用程序是如何通过套接字来维持一个连接的?

  首先,服务器应用程序用系统调用socket来创建一个套接字,它是系统分配给该服务器进程的类似文件描述符的资源,它不能与其它进程共享。

  接下来,服务器进程会给套接字起个名字。本地套接字的名字是Linux文件系统中的文件名,一般放在/temp或/user/tmp目录中。对于网络套接字,它的名字是与客户连接的

特定网络有关的服务标识符(端口号或访问点)。这个标识符允许Linux将进入的针对特定端口号的连接转到正确的服务器进程。

  例如,Web服务器一般在80端口上创建一个套接字,这是一个专门用于次目的的标识符。Web浏览器知道对于用户想要访问的Web站点,应该使用端口80来建立HTTP连接。

我们用系统调用bind来给套接字命令。然后服务器进程就开始等待客户连接到这个命名套接字。系统调用listen的作用是,创建一个队列并将其用于存放来自客户的进入连接。

服务器通过系统调用accept来接受客户的连接。

  服务器调用accept时,它会创建一个与原有的命名套接字不同的新的套接字。这个新套接字只用于与这个特定的客户进行通信,而命名套接字则被保留下来继续处理来自其他客户的连接。

如果服务器编写的当,它就可以充分利用多个连接带来的好处。Web服务器就会这么做以同时服务来自许多客户的页面请求。对一个简单的服务器来说,后续的客户将在监听队列中等待,

直到服务器再次准备就绪。

  而基于套接字系统的客户端更简单。客户首先调动socket创建一个未命名套接字,然后将服务器的命名套接字作为一个地址来调用connect与服务器建立连接。

  一旦连接建立,我们就可以像使用底层的文件描述符那样用套接字来实现双向的数据通信。

3.套接字属性

  套接字的属性由三个属性确定,即域(demain) 、类型(type)、协议(protocol)。

   域:指定套接字通信中使用的网络介质。最常见的套接字域是AF_INET,它指的是Internet网络,许多Linux局域网使用的都是该网络,当然,因特网自身用的也是它。  

类型:因特网协议提供了两种通信机制:流(stream)和数据报(datagram).

流套接字提供的是一个有序、可靠、双向字节流的连接。 流套接字由类型SOCK_STREAM指定,它们是在AF_INET域中通过TCP/IP连接实现的。      

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

协议:现在先不需要考虑。。。(╯—﹏—)╯( ┷━━━┷

干货:

创建套接字

#include <sys/types.h>

#include <sys/socket.h>

 int socket(int domain, int type, int protocol)

socket系统调用创建回一个套接字并返回一个描述符,该描述符可以访问该套接字。创建的套接字是一条通信线路的一个端点。各参数就是上面提的三个属性。

套接字的地址

在AF_INET域中,套接字地址由结构体sockaddr_in来指定,该结构体的定义在头文件netinet/in.h中,它至少包含以下成员:

struct sockaddr_in{

short int sin_family; /* AF_INET*/

unsigned short int  sin_port;

struct in_addr sin_addr;

}

struct in_addr{

unsigned long int s_addr;

}

命名套接字

要想让通过socket调用创建的套接字可以被其他进程使用,服务器程序就必须给该套接字命名。这样,AF_INET套接字就会关联到一个IP端口号

#include <sys/socket.h>

int bind(int socket, const struct sockaddr *addrss, size_t address_len)

bind系统把参数address中的地址分配给文件描述符socket关联的未命名套接字。地址的长度由address_len传递。bind调用需要将一个特定的地址结构指针装换为指向

通用地址类型。

创建套接字队列

为了能够在套接字上接受进入的连接,服务器程序必须创建一个队列来保存未处理的请求,它用listen系统调用来完成这一工作。

#include <sys/socket.h>

int listen(int socket,  int backlog)

Linux系统可能会对队列中可以容纳的未处理连接的最大化数目作出限制。将这个队列长度设为backLog的值。在套接字队列中,等待处理的进入连接的个数最多不能超过这个数字。

再往后的连接将被中断,导致客户的连接请求失败。

接受连接

一旦服务器程序创建并命名了套接字之后,他就可以通过accept系统调用来等待客户建立对该套接字的连接。

#include <sys/socket.h>

int accept(int socket,  struct sockaddr *address, size_t *address_len)

accept系统调用只有当有客户程序试图连接到有socket参数指定的套接字上时才返回。这里的客户是指,在套接字队列中排在第一个的未处理的连接。accept函数将创建一个新套接字来与该客户进行

通信,并且返回新套接字的描述符。新套接字的类型和服务器监听套接字类型是一样的。

请求连接

客户程序通过在一个未命名套接字和服务器监听套接字之间建立连接的方法来来连接到服务器。

#include <sys/socket.h>

int connect(int socket,  struct sockaddr *address, size_t *address_len)

成功返回0,失败时返回-1

关闭套接字

close(int socket);

主机字节序和网络字节序

为了使不同类型的计算机可以就通过网络传输的多字节整数的值达到一致,你需要定义一个网络字节序。客户和服务器程序必须在传输之前,将它们内部的整数表达方式转换为

网络字节序。它们通过定义在头文件netinet/in.h中的函数来完成这一工作,

htonl(),hrons(),ntohl(),ntohs()   host to network long  长整数从主机字节序到网络字节序的转换。

服务器程序:

客户端:

执行效果:

Linux学习6-套接字的更多相关文章

  1. Linux之socket套接字编程20160704

    介绍套接字之前,我们先看一下传输层的协议TCP与UDP: TCP协议与UDP协议的区别 首先咱们弄清楚,TCP协议和UCP协议与TCP/IP协议的联系,很多人犯糊涂了,一直都是说TCP/IP协议与UD ...

  2. Linux Socket 原始套接字编程

    对于linux网络编程来说,可以简单的分为标准套接字编程和原始套接字编程,标准套接字主要就是应用层数据的传输,原始套接字则是可以获得不止是应用层的其他层不同协议的数据.与标准套接字相区别的主要是要开发 ...

  3. 4月20日 python学习总结 套接字工作流程

    一.套接字工作流程 一个生活中的场景.你要打电话给一个朋友,先拨号,朋友听到电话铃声后提起电话,这时你和你的朋友就建立起了连接,就可以讲话了.等交流结束,挂断电话结束此次交谈. 生活中的场景就解释了这 ...

  4. 005.TCP--拼接TCP头部IP头部,实现TCP三次握手的第一步(Linux,原始套接字)

    一.目的: 自己拼接IP头,TCP头,计算效验和,将生成的报文用原始套接字发送出去. 若使用tcpdump能监听有对方服务器的包回应,则证明TCP报文是正确的! 二.数据结构: TCP首部结构图: s ...

  5. 4月23日 python学习总结 套接字UDP和 操作系统理论,多道理论

    一.套接字UDP udp是无链接的,先启动哪一端都不会报错 UDP(user datagram protocol,用户数据报协议)是无连接的,面向消息的,提供高效率服务.不会使用块的合并优化算法,, ...

  6. linux基础编程 套接字socket 完整的服务器端多线程socket程序【转】

    转自:http://blog.csdn.net/ghostyu/article/details/7737203 此段程序来自我的一个项目中,稍微做了些修改,运行稳定,客户端程序比较简单所以未编写,可以 ...

  7. 4月19日 python学习总结 套接字模块的使用

    服务端: import socket phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 买电话 phone.bind(('127.0.0 ...

  8. 第十六章:网络IPC:套接字

    16.1.引言 上一章考查了各种Unix系统所提供的经典进程间通信(IPC)机制:管道.先进先出.消息队列.信号量以及共享内存.通过这些机制,同一台计算机上运行的进程可以相互通信.本章将考查不同计算机 ...

  9. 网络IPC:套接字之寻址

    在学习用套接字做一些有意义的事情之前,需要知道如何确定一个目标通信进程. 进程的标识有两个部分:计算机的网络地址可以帮助标识网络上想与之通信的计算机,而服务可以帮助标识计算机上特定的进程. 1.字节序 ...

  10. 套接字socket 的地址族和类型、工作原理、创建过程

    注:本分类下文章大多整理自<深入分析linux内核源代码>一书,另有参考其他一些资料如<linux内核完全剖析>.<linux c 编程一站式学习>等,只是为了更好 ...

随机推荐

  1. React笔记-首次渲染

    渲染机制 渲染机制主要分为两部分: 首次渲染和更新渲染. 首次渲染 首先通过一个小例子,来讲解首次渲染过程. <!DOCTYPE html> <html lang="en& ...

  2. 关于k8s这项大动作,预示着边缘计算迎来“开源”发展的新周期……

    在文章<最近在边缘计算领域,发生了一件足以载入物联网史册的大事…>我曾经提到Kubernetes(简称K8s)将从超大规模云计算环境,被带入到物联网边缘计算场景中. 事情有了新进展,从本周 ...

  3. 微软职位内部推荐-Principal Software Eng Mgr

    微软近期Open的职位: Job Title: &nbsp Principal Software Eng Mgr Work Location: Shanghai, China Job Desc ...

  4. 团队作业Week5

    每个团队开一个讨论会,协商讨论团队贡献分的分配方式.每个团队的团队贡献分为50分/人.每个人分数不能相同,请详细说明分数的分配规则. 可参考这个博客. 截止时间:2014-10-27

  5. 【Beta阶段】第二次Scrum Meeting!

    每日任务内容: 本次会议为第二次Scrum Meeting会议~ 由于本次会议项目经理召开时间较晚,所以在公寓7层召开,所以女生没来…召开时间大家集会10分钟,经理与后端探讨20分钟. 队员 昨日完成 ...

  6. 浅谈个人对存储区域网络SAN的理解

    存储区域网络SAN,是一种通过将网络存储设备和服务器连接起来的网络,提供计算机和存储设备间的数据传输.其中,SAN是独立于服务器系统之外的,拥有近乎无限的存储能力,通过利用光纤作为传输媒介,实现了高速 ...

  7. php 中的 “!=”和“!==”

    !==是指绝对不等于,比如,$a = 2, $b=”2″   那么,$a!==$b成立,可是$a!=$b不成立:

  8. 开机自启动nginx,php-fpm

    开机自启动nginx,php-fpm(其他服务类似) centos 7以上是用Systemd进行系统初始化的,Systemd 是 Linux 系统中最新的初始化系统(init),它主要的设计目标是克服 ...

  9. BZOJ4628 BJOI2016IP地址(trie)

    离线,每次修改相当于对该规则的所有匹配点的值+1,考虑在trie上打加法标记和匹配标记,匹配标记不下传,加法标记下传遇到匹配标记时清空.注意是用b时刻前缀-a时刻前缀,而不是(a-1)时刻前缀,具体我 ...

  10. 洛谷 P2245 星际导航 解题报告

    P2245 星际导航 题目描述 sideman做好了回到Gliese 星球的硬件准备,但是sideman的导航系统还没有完全设计好.为了方便起见,我们可以认为宇宙是一张有N 个顶点和M 条边的带权无向 ...