(转)Linux网络编程(1):套接字编程简介

  121人阅读  评论(0)  收藏  举报

        这几天借了一本网络编程的经典书籍:《UNIX网络编程(卷一:套接字联网API)》,想着学习一下网络编程。下面的内容主要依靠这本书籍,然后,结合我自己的知识和网络资源,对Linux网络编程做由浅入深的学习。


1、什么是套接字(Socket)?

         我自己的理解是:套接字,即端点、端口,是建立在应用层和传输层之间的一个概念。

         网络释义:套接字,是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。为了区别不同的应用进程和连接,许多计算机操作系统为应用进程与TCP/IP协议交互提供了“套接字接口”,以便区分不同应用进程间的网络通信和连接。

2、套接字的分类

(1)流式套接字:SOCK_STREAM;用于提供面向连接、可靠的数据传输服务,使用了传输控制协议,即TCP协议。
(2)数据包套接字:SOCK_DGRAM;用于提供了一种无连接的服务,使用UDP(User Datagram Protocol)协议进行数据的传输。

(3)原始套接字:SOCK_RAW;原始套接字可以读写内核没有处理的IP数据包,而流套接字只能读取TCP协议的数据,数据报套接字只能读取UDP协议的数据。因此,如果要访问其他协议发送数据必须使用原始套接字。

3、常用结构体和地址转换函数

1、通用套接字地址结构:struct sockaddr

[cpp]  view plain copy
  1. struct sockaddr  
  2. {  
  3.     unsigned short sa_family;  
  4.     char      sa_data[14];  
  5. }  

2、Internet下套接字地址结构:struct sockaddr_in

[cpp]  view plain copy
  1. struct sockaddr_in  
  2. {  
  3.     shortsin_family;  //通信协议族,AF_INET、AF_UNIX  
  4.     unsigned short     sin_port;//通信端口  
  5.     struct in_addrsin_addr;//IP地址  
  6.     unsigned charsin_zero[8];  
  7. }  

其中:

[cpp]  view plain copy
  1. struct in_addr    //32位IP地址  
  2. {  
  3.     unsigned long s_addr;  
  4. }  

      struct sockaddr是通用的套接字地址,而struct sockaddr_in则是internet环境下套接字的地址形式,二者长度一样,都是16个字节。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。一般情况下,需要把sockaddr_in结构强制转换成sockaddr结构再传入系统调用函数中。

3、地址转换函数

BSD网络软件中包含了两个函数,用来在二进制地址格式(网络字节序)和点分十进制字符串格式之间相互转换,但是这两个函数仅仅支持IPv4。

[cpp]  view plain copy
  1. in_addr_t   inet_addr(const char *cp);//返回32位二进制网络字节序的IPv4地址  
  2.  int      inet_aton(const char* strptr, struct in_addr *addrptr);  //将strptr所指向的字符串转换成一个32位的网络字节序二进制值,并通过指针addrptr来存储  
  3. char *    inet_ntoa(struct in_addr in);//返回指向一个点分十进制数串的指针,其中n表示32位网络字节序的IP地址,a表示点分十进制字符串  

功能相似的两个函数同时支持IPv4和IPv6

[cpp]  view plain copy
  1. const char * inet_ntop(int domain, const void *addr, char *str, socklen_t size);  
  2. int inet_pton(int domain, const char *str, void *addr);//将str所值的字符串转换成一个32位网络字节序二进制值,并通过指针addrptr来存储  

例:

[cpp]  view plain copy
  1. struct sockaddr_in servaddr;  
  2. servaddr.sin_family = AF_INET;  
  3. servaddr.sin_port = htons(8008);  
  4. inet_pton(AF_INET, argv[1], &servaddr.sin_addr);  

4、主机字节序、网络字节序和字节转换函数

主机字节序就是我们平常说的大端和小端模式,不同的 CPU 有不同的字节序类型,这些字节序是指整数在内存中保存的顺序 。最常见的有两种:
1. Little endian:将低序字节存储在起始地址
2. Big endian:将高序字节存储在起始地址
例子:在内存中双字0x01020304(DWORD)的存储方式
内存地址
4000 4001 4002 4003
LE 04 03 02 01
BE 01 02 03 04

网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。

 
 

为了进行两者之间的转换,socket提供了转换的函数 有下面四个字节转换函数:

htons() :把unsigned short类型从主机序转换到网络序

htonl () :把unsigned long类型从主机序转换到网络序

ntohs() :把unsigned short类型从网络序转换到主机序

ntohl () :把unsigned long类型从网络序转换到主机序

另外,我们要知道,16位端口号(一个整形数字),32位IPv4地址(四个整形数字)。

通常的用法是:

[cpp]  view plain copy
  1. #define MYPORT 8008  
  2. int sockfd;  
  3. struct sockaddr_in my_addr;  
  4. sockfd = socket(AF_INET, SOCK_STREAM, 0);   
  5.   
  6. my_addr.sin_family = AF_INET;  /* 主机字节序 */  
  7. my_addr.sin_addr.s_addr = inet_addr("192.168.0.1");  
  8. my_addr.sin_port = htons(MYPORT); /* short, 网络字节序 */  
  9.   
  10. bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */  
  11. //memset(&my_addr.sin_zero, 0, 8);  
  12.   
  13. bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr));  

5、常用端口号

端口:21 

服务:FTP
说明:FTP服务器所开放的端口,用于上传、下载。最常见的攻击者用于寻找打开anonymous的FTP服务器的方法。这些服务器带有可读写的目录。木马Doly Trojan、Fore、Invisible FTP、WebEx、WinCrash和Blade Runner所开放的端口。

端口:22
服务:Ssh 
说明:PcAnywhere建立的TCP和这一端口的连接可能是为了寻找ssh。这一服务有许多弱点,如果配置成特定的模式,许多使用RSAREF库的版本就会有不少的漏洞存在。

端口:23 
服务:Telnet 
说明:远程登录,入侵者在搜索远程登录UNIX的服务。大多数情况下扫描这一端口是为了找到机器运行的操作系统。还有使用其他技术,入侵者也会找到密码。木马Tiny Telnet Server就开放这个端口。

端口:25
服务:SMTP 
说明:SMTP服务器所开放的端口,用于发送邮件。入侵者寻找SMTP服务器是为了传递他们的SPAM。入侵者的帐户被关闭,他们需要连接到高带宽的E-MAIL服务器上,将简单的信息传递到不同的地址。木马Antigen、Email Password Sender、Haebu Coceda、Shtrilitz Stealth、WinPC、WinSpy都开放这个端口。

端口:53
服务:Domain Name Server(DNS) 
说明:DNS服务器所开放的端口,入侵者可能是试图进行区域传递(TCP),欺骗DNS(UDP)或隐藏其他的通信。因此防火墙常常过滤或记录此端口。

端口:80
服务:HTTP 
说明:用于网页浏览。木马Executor开放此端口。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值