Linux socket 网络编程入门

Linux下的网络编程一般即是指socket套接字编程,入门比较矮简单,网上也有很多入门的例程。不过每次看过用过以后过段时间又忘了具体的操作了,又得去查,所以在这里总结整理一下,也省了以后查别人教程的时间。

1. socket套接字流程简介

socket套接字包含标准套接字(SOCK_STREAM,SOCK_DRAGM)以及原始套接字(SOCK_RAW),一般我们进行网络编程有标准套接字就够了,但如果要实现标准套接字(即TCP,UDP套接字)不能实现的功能,就需要用原始套接字了。这里还是主要总结一下标准套接字的用法。
如前所述,标准套接字分为TCP协议(SOCK_STREAM)和UDP协议(SOCK_DRAGM)两种type的工作流程,因为TCP是面向连接的服务,所以TCP网络编程会更复杂一点。不过不论是TCP还是UDP,其socket网络编程模式都是类似的,分为客户端和服务端。

  • 客户端:在网络程序中,如果一个程序主动和外面的程序通信,那么我们把这个程序称为客户端程序。
  • 服务端: 和客户端相对应的程序即为服务端程序。被动的等待外面的程序来和自己通讯的程序称为服务端程序。

一般在网络应用中,获取服务的客户即是客户端,提供服务的服务器即是服务端,不过也有些程序是互为服务和客户端,这种情况下, 一个程序既是客户端也是服务端。 以下两图描述了TCP和UDP socket通信的流程:

  • TCP socket流程
    TCP socket流程

  • UDP socket流程
    UDP socket流程

可以看到,因为TCP是面向连接的服务,包含三次握手建立连接的过程,所以TCP的服务器模式比UDP多了listen,accept函数,TCP客户端模式比UDP多了connect函数。

2. socket标准套接字基本函数介绍

TCP socket 函数流程

这张图将TCP数据交互的流程与socket函数作了一一对应,十分清楚,接下来就对其中的函数做一个整理介绍。

2.1 创建socket套接字

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

功能介绍:

在Linux操作系统中,一切皆文件,网络程序通过socket和其它几个函数的调用,会返回一个 通讯的文件描述符,我们可以将这个描述符看成普通的文件的描述符来操作,这就是linux的设备无关性的好处。。socket函数完成正确的操作是返回值大于0的文件描述符,当返回小于0的值时,操作错误。同样是返回一个文件描述符,但是会因为三个参数组合不同,对于数据具体的工作流程不同,对于应用层编程来说,这些也是不可见的。

参数说明:

  • family:说明我们网络程序所在的主机采用的通讯协族(AF_INET和AF_UNIX等)。
    AF_UNIX只能够用于单一的Unix 系统进程间通信,
    而AF_INET是针对Internet的,因而可以允许在远程
  • type:我们网络程序所采用的通讯协议(SOCK_STREAM,SOCK_DGRAM,SOCK_RAW等)
    SOCK_STREAM表明我们用的是TCP 协议,这样会提供按顺序的,可靠,双向,面向连接的比特流。
    SOCK_DGRAM 表明我们用的是UDP协议,这样只会提供定长的,不可靠,无连接的通信。
  • protocol:具体的协议,对于标准套接字来说,其值是0,对于原始套接字来说就是具体的协议值。

2.2 地址端口绑定函数bind

int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen)

功能介绍:

bind函数主要应用于服务器模式一端,其主要的功能是将addrlen长度 struct sockaddr类型的myaddr地址与sockfd文件描述符绑定到一起,在sockaddr中主要包含服务器端的协议族类型,网络地址和端口号等。在客户端模式中不需要使用bind函数。当bind函数返回0时,为正确绑定,返回-1,则为绑定失败。

参数说明:

  • sockfd:是由socket调用返回的文件描述符。
  • my_addr:是一个指向sockaddr的指针,由于struct sockaddr数据结构类型不方便设置,所以通常会通过对truct sockaddr_in进行数值结构设置,然后进行强制类型转换成struct sockaddr类型的数据,下面有两种类型数据结构的定义和对应关系图。
  • addrlen:是sockaddr结构的长度。
typedef unsigned short  sa_family_t;
struct in_addr {
    __be32    s_addr;
};


struct sockaddr {
    sa_family_t    sa_family;       /* address family, AF_xxx       */
    char           sa_data[14];     /* 14 bytes of protocol address */
};

/* Structure describing an Internet (IP) socket address.            */
#define __SOCK_SIZE__    16         /* sizeof(struct sockaddr)      */
struct sockaddr_in {
  sa_family_t       sin_family;     /* Address family               */
  __be16            sin_port;       /* Port number                  */
  struct in_addr    sin_addr;       /* Internet address             */

  /* Pad to size of `struct sockaddr'。                  */
  unsigned char     __pad[__SOCK_SIZE__ - sizeof(short int) -
            sizeof(unsigned short int) - sizeof(struct in_addr)];
};
  • struct sockaddr_in和struct sockaddr的映射关系
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值