郁金香外挂技术-郁金香灬老师

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

郁金香终身VIP管理员QQ150330575项目合作(有实力的+)视频教程+每月更新+QQ群
飞郁视频分享(每周更新)
查看: 902|回复: 0

C语言中socket使用讲解。

[复制链接]
发表于 2019-7-2 17:14:01 | 显示全部楼层 |阅读模式
[color=rgba(0, 0, 0, 0.75)]C语言中socket转载请标明出处:http://blog.csdn.net/leafage_m https://blog.csdn.net/Leafage_M/article/details/78459799


1.socket定义。

在Linux中的网络编程是通过socket接口来进行的。其实socket接口也是一种特殊的I/O(在《深入理解计算机系统》这本书中的IO部分也有提到网络也是一种特殊的IO),它也是一种文件描述符。socket也有一个类似于打开文件的函数调用,该函数返回一个整型的socket描述符,随后的建立连接、数据传输等操作都是通过socket来实现的。


2.socket的类型。

1 .流式socket(SOCK_STREAM)
流式套接字使用的是TCP协议,由于TCP协议建立在三次握手的基础上,所以这种类型能够提供可靠的、面向连接的通信流,能够保证数据传输的正确性和顺序性。

2.数据报socket(SOCK_DGRAM)
数据报套接字使用的是UDP协议,由于UDP将数据扔出去之后就不管的桀骜特性,所以该类型定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠、无差错的。

3.原始socket
原始套接字允许对底层协议如IP或ICMP(在网络层,而TCP和UDP都在传输层)进行直接访问,功能比较强大但是使用不便,主要用于一些协议的开发。


3.存储socket信息的结构体。

在介绍socket函数的使用之前还需要介绍一下保存socket信息的结构体。在C语言中有两个重要的struct数据类型:sockaddr和sockaddr_in,这两个结构体都是用用来存储socket的相关信息的。

[color=rgb(0, 0, 136) !important]struct sockaddr {    [color=rgb(0, 0, 136) !important]unsigned [color=rgb(0, 0, 136) !important]short sa_family;[color=rgb(136, 0, 0) !important]//地址族,2字节    [color=rgb(0, 0, 136) !important]char sa_data[[color=rgb(0, 102, 102) !important]14];[color=rgb(136, 0, 0) !important]//14字节的协议地址,包含该socket的IP地址和端口号,14字节}
  • 1
  • 2
  • 3
  • 4
[color=rgb(0, 0, 136) !important]struct sockaddr_in {    [color=rgb(0, 0, 136) !important]short sa_family;[color=rgb(136, 0, 0) !important]//地址族,2字节    [color=rgb(0, 0, 136) !important]unsigned [color=rgb(0, 0, 136) !important]short [color=rgb(0, 0, 136) !important]int sin_port;[color=rgb(136, 0, 0) !important]//端口号,2字节    [color=rgb(0, 0, 136) !important]struct in_addr sin_addr;[color=rgb(136, 0, 0) !important]//IP地址,4字节    [color=rgb(0, 0, 136) !important]unsigned [color=rgb(0, 0, 136) !important]char sin_zero[];[color=rgb(136, 0, 0) !important]//填充0以保持与struct sockaddr同样大小,8字节}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在sockaddr_in中使用了in_addr的结构体:

struct [color=rgb(0, 0, 136) !important]in_addr {    [color=rgb(0, 0, 136) !important]in_addr_t s_addr;};
  • 1
  • 2
  • 3
  • 4
  • 5

表示一个32位的IPv4地址。

in_addr_t一般为32位的unsigned int,其字节顺序为网络字节序,即该无符号数采用大端字节序。其中每8位表示一个IP地址中的一个数值。

struct sockaddr是通用的套接字地址,而struct sockaddr_in则是internet环境下套接字的地址形式。

这两种结构体都是16字节,并且都存在family属性,不同的是:sockaddr使用的是14字节的sa_data,而sockaddr_in将sa_data的14字节拆分成了sin_port和sin_addr以及sin_zero。

所以这两种数据包含的内容都是一样的,明显sockaddr_in类型将地址和端口拆开更为方便(sockaddr给操作系统使用),所以一般使用sockaddr_in进行填充然后将其转换为sockaddr。

有人注意到这两种结构体都存在sa_family字段,sa_family可选的常见值定义在#include < netinet/in.h >文件下,其中可选的值有以下几种:

  • AF_INET:IPv4协议
  • AF_INET4:IPv6协议
  • AF_LOCAL:UNIX域协议
  • AF_LINK:链路地址协议
  • AF_KEY:秘钥套接字


4.地址转换。

地址的内容可以看看这片文章:IP地址的三种表示格式 及 在Socket编程中的应用

其中的重点部分:

IP地址其实有三种不同的表示格式:

   1)Ascii(网络点分字符串)   2)网络地址(32位无符号整形,网络字节序,大头)   3)主机地址 (主机字节序)
  • 1
  • 2
  • 3
  • 在Socket编程开发中,通过函数inet_addr和inet_ntoa可以实现点分字符串与网络字节顺序格式IP地址之间的转换。

  • 在Socket编程中,有四个函数来完成主机字节顺序格式和网络字节顺序格式之间的转换,它们是:htonl、htons、ntohl、和ntohs。 htons和ntohs完成16位无符号数的相互转换,htonl和ntohl完成32位无符号数的相互转换。

  • 在Linux中有一些函数可以实现主机名和地址的转换,最为常见的有gethostbyname、gethostbyaddr、getaddrinfo等,它们都可以实现IPv4和IPv6的地址和主机名之间的转换。


本人对这地址之间的关系也是一头雾水,所以不做过多解释。


5.相关函数。

先看一下使用TCP和UDP的流程图:

TCP:




郁金香外挂教程,学习中...
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

限时限量优惠

QQ|小黑屋|手机版|郁金香外挂技术-郁金香灬老师 ( 苏ICP备10059359号 )

GMT+8, 2019-9-19 08:10 , Processed in 0.050396 second(s), 18 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表