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

二 套接字属性
  套接字的特性由3个属性确定,它们是:域,类型和协议
   1 套接字的域
    域指定套接字通信中的网络介质,最常见的套接字域是AF_INET,它指的是Internet网络,其底层的协议——网际(IP)只有一个地址族,它使用一种特定的方式来指定网络中的计算机,即人们常说的IP地址。

    AF_UNIX域是UNIX文件系统域,即使是一台还没联网的计算机上的套接字也可以使用这个域,这个域的底层协议是文件输入/输出,而它的地址就是文件名。
 
  2 套接字类型
    因特网协议提供了两种通信机制:流和数据报。
    2.1 流套接字
       流套接字提供的是一个有序,可靠,双向字节流的连接,因此,发送的数据可以确保不会丢失,复制或乱序到达,并且在这一过程中发生的错误也不会显示出来。大的消息将被分片,传输,再重组。
       流套接字由类型SOCK_STREAM指定,它们是在AF_INET域中通过TCP/IP(TCP代表是传输控制协议,IP代表是网际协议)连接实现的。
    2.2 数据报套接字
     数据报套接字由类型SOCK_DGRAM指定,不建立和维持一个连接。它对可以发送的数据报的长度有限制。数据报作为一个单独的网络消息被传输,它可能会丢失,复制或乱序到达。
     数据报套接字是在AF_INET域中通过UDP/IP连接实现的,它提供的是一种无序的不可靠服务(UDP代表的是用户数据报协议)。
     数据报适用于信息服务中的“单次”查询,它主要用来提供日常状态信息或执行低优先级的日志记录。基于数据报的服务器通常不保留连接信息。
 
 三 套接字的连接过程


  1 创建套接字

#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain,      //指定协议族
       int type,       //指定这个套接字的通信类型
       int protocol     //指定使用的协议,将该参数设置为0表示默认协议
      );

  以下是协议族:   AF_UNIX:UNIX域协议(文件系统本地套接字)
            AF_INET:ARPA因特网协议(UNIX网络套接字)
         AF_ISO:ISO标准协议
         AF_NS:施乐网络系统协议
         AF_IPX:Novell IPX协议
         AF_APPLETALK:Appletalk DDS
  socket系统调用返回一个描述符,当这个套接字连接到另一端的套接字后,我们就可以用read和write系统调用,通过这个描述符来在套接字上发送和接收数据了。    
 
  2 套接字地址
   每个套接字域都有其自己的地址格式,对于AF_UNIX域套接字来说,它的地址有结构sockaddr_un来描述,该结构定义在头文件sys/un.h中

#include <sys/un.h>
struct sockaddr_un{
sa_family_t sun_family;//AF_UNIX
char sun_path[];//pathname,长度限制为108个字符
};

  对于AF_INET域,套接字地址由结构sockaddr_in来指定,该结构定义在头文件netinet/in.h中, 一个AF_INET套接字由它的域,端口号和IP地址来完全确定。

#include <netinet/in.h>
struct sockaddr_in{
short int sin_family;         //AF_INET;
unsigned short int sin_port;    //端口号
struct in_addr sin_addr;      //IP地址
};

  IP地址结构in_addr被定义为:

struct in_addr{
unsigned long int s_addr;    //使用inet_addr(const char *cp)函数将一个点分十进制的IP转换成一个长整数型数
};

  3 命名套接字
   通过给套接字命名,可以让创建的套接字被其他进程使用

#include <sys/socket.h>
int bind(int socket,                //创建的socket
      const struct sockaddr *address,    //套接字地址地址,在AF_INET域中则是struct sockaddr_in类型,在AF_UNIX域中则是struct sockaddr_un类型
      size_t address_len                //地址结构的长度
     );                      //bind调用在成功时返回0,失败时返回-1并设置errno

  bind系统调用把参数address中的地址分配给与文件描述符socket关联的为命名套接字,地址结构的长度由参数address_len传递。


  errno的值              描述


  EBADF              文件描述符无效
  ENOTSOCK             文件描述符对应的不是一个套接字
  EINVAL                文件描述符对应的是一个已命名的套接字
  EADDRNOTAVAIL         地址不可用
  EADDRINUSE            地址已经绑定了一个套接字

  EACCESS             权限不足
  ENOTDIR,ENAMETOOLONG   表明选择的文件不符合要求


  4 创建套接字队列
  创建套接字队列能够保存服务器未处理的请求

#include <sys/socket.h>
int listen(int socket,     //socket文件标识符
       int backlog    //用来设置队列中可以容纳的未处理连接的最大数目,超过这个数目,往后的连接将被拒绝,导致客户的连接请求失败。
      );          //listen函数在成功时返回0,失败时返回-1

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

#include <sys/socket.h>
int connect(int socket,                //指定的套接字将连接到参数address指定的服务器套接字
       const struct sockaddr* address,    //这个和服务器端的bind操作部分一样,看步骤2,3
       size_t address_len            //指定address指向的结构的长度
       );                     //成功时,connect调用返回0,失败时返回-1并设置errno

    errno值              描述


    EBADF            传递给socket参数的文件描述符无效
    EALREADY          该套接字上已经有一个正在进行中的连接
    ETIMEOUT          连接超时
    ECONNREFUSED       连接请求被服务器拒绝


  如果连接不能立刻建立,connect调用将阻塞一段超时时间,一旦这个超时时间到达,连接将被放弃,connect调用失败。但如果connect调用被一个信号中断,而该信号又得到了处理,connect调用还是会失败
  connect的阻塞特性可以通过设置该文件描述符的O_NONBLOCK标志来改变。

int flags=fcntl(socket,F_GETFL,);
fcntl(socket,O_NONBLOCK|flags);

  6 服务器接受连接

#include <sys/socket.h>
int accept(int socket,              //客户程序连接到由socket参数指定的套接字上
       struct sockaddr *address,     //客户的地址,如果我们不关心客户的地址,可以将address参数指定为空指针
       size_t *address_len        //客户地址的长度,如果客户地址的长度超过这个值,它将被截断。
      );

  accept系统调用只有当有客户程序试图连接到由socket参数指定的套接字上时才返回,这里的客户是指套接字队列中排在第一个的未处理的连接。
  一般情况下,如果套接字队列中没有未处理的连接,accept将阻塞(程序将暂停)直到有客户建立连接为止,和请求连接一样,可以通过使用fcntl函数对套接字文件描述符设置O_NONBLOCK标志
  当有未处理的客户连接时,accept函数将返回一个新的套接字文件描述符。

  7 关闭连接
  close系统用来结束套接字连接。

四 示例

服务器程序server.c

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h> int main(){
int server_sockfd,client_sockfd;
int server_len,client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
//为服务器创建一个未命名的套接字
server_sockfd=socket(AF_INET,SOCK_STREAM,);
//命名套接字
server_address.sin_family=AF_INET;
server_address.sin_addr.s_addr=inet_addr("127.0.0.1");
server_address.sin_port=;
server_len=sizeof(server_address);
bind(server_sockfd,(struct sockaddr *)&server_address,server_len);
//创建一个连接队列,开始等待客户进行连接
listen(server_sockfd,);
while(){
char ch;
printf("server waiting\n");
//接受一个连接
client_len=sizeof(client_address);
client_sockfd=accept(server_sockfd,(struct sockaddr*)&client_address,&client_len);
//对client_sockfd套接字上的客户进行读写操作
read(client_sockfd,&ch,);
ch++;
write(client_sockfd,&ch,);
close(client_sockfd);
}
}

客户程序client.c

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h> int main(){
int sockfd;
int len;
struct sockaddr_in address;
int result;
char ch='A';
//为客户创建一个套接字
sockfd=socket(AF_INET,SOCK_STREAM,);
//命名套接字,与服务器保持一致
address.sin_family=AF_INET;
address.sin_addr.s_addr=inet_addr("127.0.0.1");
address.sin_port=;
len=sizeof(address);
//将我们的套接字连接到服务器的套接字
result=connect(sockfd,(struct sockaddr*)&address,len);
if(result==-){
perror("oops:client1");
exit();
}
//现在就可以通过sockfd进行读写操作了
write(sockfd,&ch,);
read(sockfd,&ch,);
printf("char from server=%c\n",ch);
close(sockfd);
exit();
}

  

Linux学习笔记30——套接字的更多相关文章

  1. linux学习笔记之套接字

    一.基础知识. 1:套接字基础. 1,是通信端点的抽象. 2,在UNIX类系统中被当作是一种文件描述符. 3,套接字通信域. 域 描述 AF_INET IPV4因特网域 AF_INET6 IPV6因特 ...

  2. 网络协议学习笔记(五)套接字Socket

    概述 前面学习网络知识的时候写过一篇关于套接字的随笔见<JAVA SOCKET 详解>,现在本人正在系统的学习网络知识,现在除了温故知新之外,在详细的学习记录一下套接字的知识. Socke ...

  3. Linux 学习笔记

    Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...

  4. deepin linux学习笔记

    目录 deepin linux学习笔记 前言 linux常用命令 ls 显示文件夹内容 cd 切换当前目录 pwd 查看当前工作目录 mkdir 新建文件夹 rm 删除文件或文件夹 mv 移动文件 c ...

  5. (转)Linux最常用指令及快捷键 Linux学习笔记

    Linux最常用指令及快捷键 Linux学习笔记 原文:http://blog.csdn.net/yanghongche/article/details/50827478 [摘自 鸟叔的私房菜]--转 ...

  6. linux学习笔记2-linux的常用命令

    第一篇博客:linux学习笔记1-ubuntu的安装与基本设置 之中,已经介绍了如何安装linux操作系统,以及一些基本的设置修改. 本篇博客主要介绍linux中的一些常用的终端命令 ======== ...

  7. deepin linux 学习笔记(二)——文本编辑器

    目录 deepin linux 学习笔记(二)--文本编辑器 前言 nano 小巧的命令行编辑器 通用 编辑 定位 排版 配置 vim 思路独特的超级编辑器 命令模式 插入模式 底线模式(末行模式) ...

  8. linux学习笔记2 - linux常用命令

    转载请标注原链接:http://www.cnblogs.com/xczyd/p/5543731.html 第一篇博客:linux学习笔记1-ubuntu的安装与基本设置 之中,已经介绍了如何安装lin ...

  9. Linux 学习笔记之超详细基础linux命令 Part 1

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122   说明:主要是在REHL Server 6操作系统下进行的测试 --字符界面虚拟终端与图形界面之间的切 方法:[ ...

随机推荐

  1. 学习java随笔第三篇:java的基本数据类型

    数据类型 一:整型 1.十进制 2.八进制 八进制数是满8进1,包含0~7的8个数字,在整数前面添加一个"0",表示是八进制数. 3.十六进制 十六进制数是满16进1,包含0~9, ...

  2. 源码心德`Context`类

    Context,中文直译为“上下文”,SDK中对其说明如下: Interface to global information about an application environment. Thi ...

  3. mvc在页面上显示PDF

    今天看到需求要在页面上显示pdf,自己整了半天,啥效果都没有,偶尔有效果还各种不兼容,很无语的说.捣鼓了半天,没办法了,去谷歌了下,介绍了各种插件,各种方法,但是都挺繁琐的,本人不是一个很喜欢使用插件 ...

  4. pat_1009

    1009. 说反话 (20) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 给定一句英语,要求你编写程序,将句中 ...

  5. Ubuntu下Hadoop快速安装手册

    http://www.linuxidc.com/Linux/2012-02/53106.htm 一.环境 Ubuntu 10.10+jdk1.6 二.下载&安装程序 1.1 Apache Ha ...

  6. Hibernate session flush

    最近做项目时,用到了hibernnate,批量删除10000条数据时,删除时前台将id传到后台,用in匹配去删除,页面直接卡死. 解决方法,将传过来的10000条id分批删除,每删除五百条后,调用ge ...

  7. 2.Oracle11g体系结构

    2.1逻辑存储结构 2.1.1数据块(Data Blocks) 数据块是Oracle逻辑结构中最小的逻辑单位,也是执行数据库输入输出最小的存储单位.通常Oracle数据库是操作系统块的整数倍,如果操作 ...

  8. Eclipse不能自动编译 java文件,不会生成CLASS

    每次修改类代码后都得重启 Tomcat 花了1天终于解决,网上所说基本是下面1和2的方法,使用之后还是不行最后重新建工作环境导入项目对比了一下找到第三种方法 1.Project 下有个 "B ...

  9. 逻辑回归:使用SGD(Stochastic Gradient Descent)进行大规模机器学习

    Mahout学习算法训练模型 mahout提供了许多分类算法,但许多被设计来处理非常大的数据集,因此可能会有点麻烦.另一方面,有些很容易上手,因为,虽然依然可扩展性,它们具有低开销小的数据集.这样一个 ...

  10. 线性回顾-generalize issue

    Ein的平均,Eout的平均 用这个平均来justify linear regresssion能够用的很好 noise level 资料里有多少的杂讯 等一下要证明的事情 predictions + ...