IPv4地址的分类
IPv4使用的是32位IP地址格式。根据前8位来区别IP地址的类型,也就是第一个点号(.)前的数字决定IP地址的类别
A类:0~127(A类主要分配给拥有大量主机的网络,例如大公司),获取这个类较难
B类:128~191(通常分配给结点比较多的网路,例如区域网)
C类:192~223(通常分配给结点比较少的网络),最常见的类
D类:224~239(用于组播)
E类:240~255(保留地址,目前没有使用)
Internet特殊的地址:
1、255.255.255.255:有限广播地址,通常用于无盘启动的工作站向服务器获取IP地址时最初使用的地址
2、0.0.0.0:主机本身,发往此IP的数据分组由本级接收
3、127.0.0.1:回环接口,常用于本地软件测试(实际上127.0.0.0 - 127.255.255.255)这2^24个地址都是
回环地址,所有发往这些地址的数据包都会被loop back。
IP地址的组成:
类别+网络ID(该类别下的第几层网络)+主机ID(该层网络下的第几台计算机)
子网掩码(subnet mask address)
1、缺省(自动生成),绝大部分情况下都是这种类型
作用: 把IP地址中的 32bit 划分为网络标识(类型+网络ID)和 主机标识(主机ID)两部分,
网络标识置1,主机标识置0。
A类网络缺省子网掩码:255.0.0.0
B类网络缺省子网掩码:255.255.0.0
C类网络缺省子网掩码:255.255.255.0
子网掩码告知路由器,地址的哪一部分是网络地址,哪一部分是主机地址,
使路由器正确判断任意IP地址是否是本网段的,从而正确地进行路由。
网络上,数据从一个地方传到另外一个地方,是依靠IP寻址。
从逻辑上来讲,是两步的:
第一步,从IP中找到所属的网络,好比是去找这个人是哪个小区的;
第二步,再从IP 中找到主机在这个网络中的位置,好比是在小区里面找到这个人。
只有网络标识相同的两台主机在无路由的情况下才能相互通信。
2、自定义子网掩码(比较少用)
自定义子网掩码是将一个网络划分为几个子网,需要每一段使用不同的网络号或子网号,
实际上我们可以认为是将主机号分为两个部分:子网号、子网主机号。
形式如下:
未做子网划分的IP地址:网络号+主机号
做子网划分后的IP地址:网络号+子网号+子网主机号
也就是说IP地址在划分子网后,以前的主机号位置的一部分给了子网号,余下的是子网主机号。
子网掩码是32位二进制数,它的子网主机标识用部分为全“0”。利用子网掩码可以判断两台主机是否在同一子网中。
若两台主机的IP地址分别与它们的子网掩码相“与”后的结果相同,则说明这两台主机在同一子网中。
一句话:将一个较大的内部网络划分为更多个小规模的子网
端口(16位的整数值)
端口的作用是用于主机内部的,因为主机内部会同时运行很多应用程序,每个应用程序之间的数据都应该是独立的,互不干扰的,端口就相当于银行窗口,相应的业务要去相应的窗口办理,这样处理的效率高,而且也不会乱。
通常情况:
(小于)<1024的端口为保留端口,系统调用。
(大于等于)>=1024为用户应用程序端口
TCP代码
服务器
#include <sys/types.h>
#include <sys/socket.h>
#include "stdio.h"
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
ssize_t recv_num;
int mysock,consock;
char recvbuf[1024];
mysock = socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in serveradd;
memset(&serveradd,0,sizeof(serveradd));
serveradd.sin_family = AF_INET;
serveradd.sin_port = htons(12250);
serveradd.sin_addr.s_addr = INADDR_ANY;
socklen_t addrlen = sizeof(serveradd);
bind(mysock , (struct sockaddr *)&serveradd , sizeof(serveradd));
listen(mysock,3);
printf("开始监听\n");
consock = accept(mysock, (struct sockaddr*)&serveradd , &addrlen);
if( consock != -1 )
{
printf("连接成功\n");
while(1)
{
memset(recvbuf,0,sizeof(recvbuf));
recv_num = recv(consock,recvbuf,sizeof(recvbuf),0);
if( recv_num > 0 )
{
}
else
{
close(file_fd);
close(consock);
consock = -1;
break;
}
}
}
return 0;
}
客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
char buf[256];
int client_socket;
ssize_t recv_num;
struct sockaddr_in server_address;
char server_ip[30] = "xxx.xxx.xxx.xxx"; // 服务器IP地址
int server_port = xxx; // 服务器端口号
// 创建套接字
client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == -1)
{
printf("Error creating socket");
return -2;
}
// 设置服务器地址结构
server_address.sin_family = AF_INET;
server_address.sin_port = htons(server_port );
inet_pton(AF_INET, server_ip, &server_address.sin_addr);
// 连接到服务器
if(connect(client_socket, (struct sockaddr *)&server_address, sizeof(server_address)) != -1)
{
printf("connect sucessful\n");
memset(buf,0,sizeof(buf));
send(client_socket, buf, recv_num , 0);
}
// 关闭套接字
close(client_socket);
return 0;
}