您的位置:首页 > 理论基础 > 计算机网络

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

2014-01-13 10:37 295 查看
2013-10-19 16:47 121人阅读 评论(0) 收藏 举报

目录(?)[-]

什么是套接字Socket
套接字的分类
常用结构体和地址转换函数
主机字节序网络字节序和字节转换函数
常用端口号

这几天借了一本网络编程的经典书籍:《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
plaincopy

struct sockaddr

{

unsigned short sa_family;

char sa_data[14];

}

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

[cpp] view
plaincopy

struct sockaddr_in

{

shortsin_family; //通信协议族,AF_INET、AF_UNIX

unsigned short sin_port;//通信端口

struct in_addrsin_addr;//IP地址

unsigned charsin_zero[8];

}

其中:

[cpp] view
plaincopy

struct in_addr //32位IP地址

{

unsigned long s_addr;

}

struct sockaddr是通用的套接字地址,而struct sockaddr_in则是internet环境下套接字的地址形式,二者长度一样,都是16个字节。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。一般情况下,需要把sockaddr_in结构强制转换成sockaddr结构再传入系统调用函数中。
3、地址转换函数
BSD网络软件中包含了两个函数,用来在二进制地址格式(网络字节序)和点分十进制字符串格式之间相互转换,但是这两个函数仅仅支持IPv4。

[cpp] view
plaincopy

in_addr_t inet_addr(const char *cp);//返回32位二进制网络字节序的IPv4地址

int inet_aton(const char* strptr, struct in_addr *addrptr); //将strptr所指向的字符串转换成一个32位的网络字节序二进制值,并通过指针addrptr来存储

char * inet_ntoa(struct in_addr in);//返回指向一个点分十进制数串的指针,其中n表示32位网络字节序的IP地址,a表示点分十进制字符串

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

[cpp] view
plaincopy

const char * inet_ntop(int domain, const void *addr, char *str, socklen_t size);

int inet_pton(int domain, const char *str, void *addr);//将str所值的字符串转换成一个32位网络字节序二进制值,并通过指针addrptr来存储

例:

[cpp] view
plaincopy

struct sockaddr_in servaddr;

servaddr.sin_family = AF_INET;

servaddr.sin_port = htons(8008);

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
plaincopy

#define MYPORT 8008

int sockfd;

struct sockaddr_in my_addr;

sockfd = socket(AF_INET, SOCK_STREAM, 0);

my_addr.sin_family = AF_INET; /* 主机字节序 */

my_addr.sin_addr.s_addr = inet_addr("192.168.0.1");

my_addr.sin_port = htons(MYPORT); /* short, 网络字节序 */

bzero(&(my_addr.sin_zero), 8); /* zero the rest of the struct */

//memset(&my_addr.sin_zero, 0, 8);

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开放此端口。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: