socket基础知识

简介:

socket 基础知识

概述

socket  TCP/IP 协议的最流行的一种网络编程接口。它与 TCP/IP 一起最早实现于 4.1BSD UNIX 系统中,主要用于传送级( TCP,UDP )编程。

socket 往往称为套接口,套接口用于网络中两个通信实体间的通信,两个实体可以存在于同一机器的不同进程中或不同机器的进程中。

套接口就好像 UNIX  pipe (管道),通信双方进程通过它来与对方发送或接受数据。如同 pipe 用文件描述字表示一样,socket 也用文件描述字表示,也称为套接口描述字,或简称套接字。在网络编程时要用套接字表示通信的对方。但两者不同的是, pipe 的通信双方在一台机器上,共用一个 pipe ,双方使用不同的文件描述字;而 socket 通信双方一般在不同机器上,因而通信双方均有一 socket 和对应的套接字负责通信,当然他们之间必须连接起来。

网络中每个通信实体的 socket 是用一个三元组标识的。三元组指的是:协议族(地址族),网络地址、和传输层端口 (本文目前只介绍 Ipv4 )。通信双方的一个连接是用网络五元组来标识的,它是由双方相同协议族的两个本地三元组合成的。网络五元组指的是:协议族(地址族)、本地网络地址、本地端口、远程网络地址和远程端口。 上述五元组往往称为全相关。而三元组往往称为半相关

套接口分为若干类型,常用的是 SOCK_STREAM  SOCK_DGRAM  SOCK_STREAM 是面向连接的套接字,使用的协议是 TCP ,通信的双方通过三次握手建立起虚拟的连接线路,通信的过程是可靠的。而 SOCK_DGRAM 是面向非连接的套接字,使用的协议是 UDP ,通信双方以数据包的方式进行通信,通信的可靠性就不能得到保证。本项目要求采用 SOCK_STREAM 类型。

 

客户机 / 服务器计算模式

  在 TCP/IP 网络应用中 , 通信双方相互作用采用客户 / 服务器模式 , 即客户端向服务器发出请求 , 服务器接收到请求后提供相应的服务。一种常见的面向连接的运行方式如下:

服务器方(首先启动):

1. 打开一通信通道并告知本地主机,它愿意在某一公认地址端口上 ( 周知口,如 http  80) 接受客户请求。

2. 等待客户请求到达该端口。

3. 接收并处理该请求,发送处理结果。如果是并发服务器,则要建立( fork )一新的子进程来处理这个客户请求。服务完成后,关闭这个新进程与客户的通信连接,并终止该进程。

4. 返回第二步,等待下一个客户请求。

客户方 :

1. 打开一通信通道,并连接到服务器所在主机的特定端口。

2 .如服务器接受了这个连接,则向它发出服务请求报文,等待并接收应答;

3. 请求结束后关闭通信通道。

 

从上面的运行过程可知:

1 .客户与服务器进程的作用是非对称的。

2. 服务进程一般是先于客户请求启动的。只要系统运行,该进程一直存在,直到正常终止或者强迫终止。

 

五元组格式(协议,本地 IP ,本地端口,远方 IP ,远方端口)的建立过程

服务器一般都有两个功能:监听  处理

在监听的时候,协议 / 本地 IP/ 本地端口(监听端口)都是确定的,当收到客户端的报文时,远方 IP 就是报文的源 IP 地址,远方端口就是报文的源端口,这样一来五元组就确定了。

然后服务器进入处理阶段,需要开启一个新的线程与客户端交互,当然就需要确定一个新的五元组,这时候协议 / 本地 IP/ 远方IP/ 远方端口都来自监听阶段确定的五元组,而本地端口会在 1024 以上随机选取 (不再使用监听端口,以便监听其他客户端的请求)。

客户端的话正好相反,在发送请求时采用随机的本地端口 ,而接受响应时采用服务器的源端口作为远方端口。

 

系统调用

1.  创建套接字

#include <sys/types.h>;

#include <sys/socket.h>;

int socket(int family, int type, int protocol);

这是进行套接字通信的第一步,就是创建套接口。参数 family 表示所使用的协议族。参数 type 可以是 SOCK_STREAM SOCK_DGRAM  SOCK_STREAM 是指面向连接的通信,而 SOCK_DGRAM 是面向非连接的数据报方式。参数 protocol 描述的是协议种类,一般设为 0 

Socket 函数用于建立三元组中的协议族部分 

此系统调用如果成功就返回的是套接字,以后的所有的对此套接口的操作都需引用这个描述字。如果调用失败,就返回 -1 ,并在全局变量 errno 保存错误的类型。

2. 绑定套接字

#include <sys/types.h>;

#include <sys/socket.h>;

int bind(int sockfd, cost struct sockaddr * saddr,  socklen_t addrlen);

bind( ) 系统调用的作用是将由 socket( ) 所创建的套接字和地址结构 sockaddr 的一个实例相关联,其中含有本地的信息如 IP 地址、端口号。

bind 函数用于建立三元组中的本地 IP 地址和本地端口号部分。

参数 sockfd 是在此前用 socket 系统调用创建的套接字, sa 是指向结构 sockaddr 一个实例的指针。这个实例的类型一般是sockaddr_in ,在调用时需要进行强制转换( struct sockaddr *  &saddr (其中 saddr  sockaddr_in 类型)。参数addrlen 是结构 sockaddr 的大小即 sizeof  struct sockaddr )。其中套接字的地址和端口可以在程序中指定,也可以由系统分配。

3. 监听

#include <sys/socket.h>;

int listen( int sockfd, int backlog ) 

 TCP 进行网络通信,服务器端要经历几个状态,当调用 socket( )  bind( ) 后,虽然套接字已经建立起来,但是其状态是CLOSED 即关闭状态。要进行通信就必须将套接字打开。对于服务器端来说要被动打开,这就是 listen( ) 的功能。

下面就可以用 accept( )  connect() 建立连接。这个过程其实就是 TCP 的“三次握手”。

4. 接受连接

#include <sys/socket.h>;

int accept( int sockfd, struct sockaddr * client_addr, socklen_t *addrlen);

服务器调用 accept( ) 来接受连接。当客户与服务器连接( connect )并且连接成功(三次握手)后 accept 则返回另一个套接字。这个新创建的套接字称为“连接套接字 ”。服务器利用这个套接字来传输数据。而前面用 socket( ) 调用产生的套接字则称之为“监听套接字”,这个套接字专门监听来自客户端的请求。

参数 sockfd 是由 socket( ) 创建的连接套接字。 client_addr 是指向结构 sockaddr 的一个实例的指针,在返回时用来存放请求连接的客户端的 IP 地址、端口信息。参数 addrlen 存放结构 * client_addr 的大小。

access 完成后通信双方两个三元组组成的五元组就建立起来了。

5. 连接服务器

#include <sys/types.h>;

#include <sys/socket.h>;

int connect(int sockfd, const struct sockaddr *serv_addr,  socklen_t addrlen);

客户端使用这个系统调用来连接目的主机(服务器)的指定端口,以便和目的主机 (  access 中等待 ) 进行通信。

sockfd 是客户机的系统调用 socket() 返回的套接字。 serv_addr 指向目的地 ( 服务器)端口和 IP 地址的数据结构 struct sockaddr  addrlen 设置为 sizeof(struct sockaddr) 

connect 完成后通信双方两个三元组组成的五元组就建立起来了。

本文转自 zhenjing 博客园博客,原文链接:  http://www.cnblogs.com/zhenjing/archive/2011/04/20/2021772.html  ,如需转载请自行联系原作者

相关文章
|
6月前
|
存储 网络协议 API
14.1 Socket 套接字编程入门
Winsock是Windows操作系统上的套接字API,用于在网络上进行数据通信。套接字通信是一种允许应用程序在计算机网络上进行实时数据交换的技术。通过使用Windows提供的API,应用程序可以创建一个套接字来进行数据通信。这个套接字可以绑定到一个端口,以允许其他应用程序连接它。另外,Winsock可以使用TCP/IP、UDP等协议来完成不同类型的数据传输任务。在网络应用程序开发中,套接字通信可以帮助应用程序开发者实现客户端/服务端模型,并实现数据的可靠传输。一般套接字通信需要经历,创建套接字(Socket),绑定(Bind),监听(Listen),接受(Accept),连接(Connect
35 0
14.1 Socket 套接字编程入门
|
9月前
|
存储 程序员 Linux
网络编程socket(上)(三)
网络编程socket(上)
56 0
|
2月前
|
网络协议 Java
【JavaEE初阶】 网络编程基础与Socket套接字
【JavaEE初阶】 网络编程基础与Socket套接字
|
2月前
|
Java
[Java]Socket套接字(网络编程入门)
[Java]Socket套接字(网络编程入门)
38 0
|
3月前
|
网络协议 Linux 定位技术
网络编程函数小总结与初识socket
总结服务器端的函数和客户端的函数 再次声明博主写的都是对于linux下的网络编程,没有写关于Windows的网络编程,也许以后会写到。 这里只是总结一下,具体参数的含义等后面的跟新
26 0
|
8月前
|
网络协议 Java API
【网络原理】网络编程Socket套接字基础知识汇总
【网络原理】网络编程Socket套接字基础知识汇总
|
9月前
|
存储 监控 网络协议
网络编程socket(上)(二)
网络编程socket(上)
68 0
|
9月前
|
存储 消息中间件 网络协议
网络编程socket(上)(一)
网络编程socket(上)
60 0
|
9月前
|
存储 网络协议 程序员
网络编程socket(下)(一)
网络编程socket(下)
39 0
|
9月前
|
监控 网络协议
网络编程socket(下)(二)
网络编程socket(下)(二)
40 0