一 TCP/IP协议概述
1 OSI参考模型与TCP/IP参考模型
OSI参考模型:应用层、表示层、会话层、传输层、网络层、数据链路层及物理层。
TCP/IP参考模型:
应用层:负责应用程序的网络访问,这里通过端口号来识别不同的进程。
http ftp
传输层:负责端对端之间的通信会话连接与建立,传输协议的选择根据数据传输方式而定。
tcp udp
网络层:负责将数据侦封装成IP数据报,并运行必要的路由算法。
icmp igmp ipv4 ipv6
网络接口层:负责将二进制流转换为数据侦,并进行数据侦的发送和接收,要注意的是数据振是独立的网络信息传输单元。
arp rarp mpls

ARP:用于获得同一物理网络中的硬件主机地址
MPLS:多协议标签协议
IP:负责在主机和网络之间寻址和路由数据包
ICMP:用于发送报告有关数据包的传送错误的协议
IGMP:被IP主机用来向本地多路广播路由器报告主机组成员的协议
TCP:为应用程序提供可靠的通信连接,适合一次传输大连数据的情况,并适用于要求得到相应的应用程序。
UDP:提供了无连接通信,且不对传送包进行可靠的保证。适合一次传输少量数据。

TCP实体所采用的基本协议是滑动窗口协议。

UDP 用户数据报协议,无连接嫌疑。

协议的选择
a 对数据可靠性的要求
验证、密码字段的传送使用TCP
对数据的可靠性要求不高的应用可以选择UDP

b 应用的实时性
TCP协议在传送过程中要进行三次握手,使用TCP协议会有较大的时间延迟。

c 网络的可靠性
广域网用TCP
局域网用UDP

二 网络编程基础

1 socket
每一个socket都用一个半相关描述[协议,本地地址,本地端口]
一个完整的套接字则用一个相关描述[协议,本地地址,本地端口,远程地址,远程端口]

2 socket类型
a 流式socket(SOCK_STREAM)
提供可靠的、面向连接的通信流;它使用TCP协议,从而保证了数据传输的正确性和顺序性

b 数据报socket SOCK_DGRAM
定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠的、无差错的,使用UDP

c 原始socket
主要用于协议的开发

二 地址及顺序处理

1 地址结构相关处理
struct sockaddr{
    unsigned short sa_family;//地址族
    char sa_data[14];//14字节的协议地址,包含该socket的IP地址和端口号。
}

struct sockaddr_in{
    short sa_family;
    unsigned short sin_port;端口号
    struct in_add sin_addr;IP地址
    unsigned char sin_zero[8];填充0
}

sa_family:
AF_INET:IPv4协议
AF_INET6:IPv6协议
AF_LOCAL:UNIX域协议
AF_LINK:链路地址协议
AF_KEY:密钥套接字

2 数据存储优先顺序
Internet上数据以高字节优先顺序在网络上传输
htons,ntohs,htonl,ntohl
h:host
n:network
s:short
l:long

#include<netinet/in.h>
uint16_t htons(unit16_t host16bit);
uint32_t htonl(unit32_t host32bit);

uint16_t ntohs(unit16_t net16bit);
uint32_t ntohl(unit32_t net32bit);

host16bit:主机字节序的16bit数据
host32bit:主机字节序的32bit数据
函数返回值:成功返回要转换的字节序,出错返回-1

3 地址格式转化

inet_aton,inet_addr inet_ntoa
inet_pton inet_netop

inet_pton:将点分十进制映射为二进制地址
inet_netop:将二进制地址映射为点分十进制地址
#include <arpa/inet.h>
int inet_pton(int family,const char *src,void *dst)
family:
AF_INET:ipv4
AF_INET6:ipv6

src:要转化的值
dst:转化后的值

转化字符串src到网络地址结构,然后将网络地址复制到dst。
in_addr  ipv4
in6_addr ipv6

const char *inet_ntop(int af,const void *src,char *dst,socklen_t size);


#include <arpa/inet.h>
char IPdotdec[20];   //存放点分十进制IP地址
struct in_addr s;      // IPv4地址结构体

int main (void)
{
    // 输入IP地址
    printf("Please input IP address: ");
    scanf("%s",IPdotdec);
    // 转换
    inet_pton(AF_INET, IPdotdec, (void *)&s);
    printf("inet_pton: 0x%x\n", s.s_addr); // 注意得到的字节序
    // 反转换
    inet_ntop(AF_INET, (void *)&s, IPdotdec, 16);
    printf("inet_ntop: %s\n", IPdotdec);
   
}

4 名字地址转化
gethostbyname
gehostbyadd
getaddrinfo

struct hostent{
    char *h_name;正是主机名
    char **h_aliases;主机别名
    int h_addrtype;地址类型
    int h_length;地址长度
    char **h_addr_list;指向IPV4或IPV6的地址指针数组
}

struct addrinfo{
    int ai_flags;AI_PASSIVE,AI_CANONNAME
    int ai_family;地址族
    int ai_socktype;socket类型
    int ai_protocol;协议类型
    size_t ai_addrlen;地址长度
    char *ai_canoname;主机名
    struct sockaddr *ar_addr;socket结构体
    struct addrinfo *ai_next;下一个指针链表
}

#include<netdb.h>
struct hostent *gthostbyname(const char *name);

过时的函数,应该使用getaddrinfo()和getnameinfo()函数替代。

int getaddrinfo(const char *node,const char *service,const struct addrino *hints,struct addrinfo **res);

5 socket基础编程
socket:用于建立一个socket连接,可指定socket类型等信息,在建立socket连接后,可对socketadd或sockaddr_in进行初始化,以保存所建立的socket信息。

bind:将本地IP地址帮定端口号,主要用于TCP的连接

connect:用于bind之后的client端,用于与服务器建立连接

send和recv:用于接收和发送数据,可以用于TCP,UDP,当用于UDP时,应在connect建立之后再用。

sendto和recefrom,在TCP中,后面的几个与地址有关的参数不起作用,函数等同于send和recv。在UDP中,可以用在之前没有使用connect的情况下,这两个函数可以自动寻找制定地址并进行连接。

#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain,int type,int protocol);

domain:
       AF_UNIX, AF_LOCAL   Local communication              unix(7)
       AF_INET             IPv4 Internet protocols          ip(7)
       AF_INET6            IPv6 Internet protocols          ipv6(7)
       AF_IPX              IPX - Novell protocols
       AF_NETLINK          Kernel user interface device     netlink(7)
       AF_X25              ITU-T X.25 / ISO-8208 protocol   x25(7)
       AF_AX25             Amateur radio AX.25 protocol
       AF_ATMPVC           Access to raw ATM PVCs
       AF_APPLETALK        Appletalk                        ddp(7)
       AF_PACKET           Low level packet interface       packet(7)

int bind(int socket,const struct sockaddr *address,socklen_t address_len);

socktd:套接字描述符
address:本地地址
addrlen:地址长度
 posted on 2009-07-15 14:45  清水湾  阅读(445)  评论(0)    收藏  举报