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

网络编程基础+UDP的实现

2016-03-17 15:32 567 查看
网络地址分类(32位网络地址)

A类地址:第一个字节为网络地址,其他3个字节主机地址,第一字节的最高位固定为0

从1.0.0.1------126.255.255.255

B类地址:第一字节和第二字节为网络地址,其他2个字节为主机地址,第一字节前两位固定为10

从128.0.0.1---191.255.255.255

C类地址:前三个字节为网络地址,最后一个字节是主机地址,第一字节的前三位固定为110

从192.0.0.1----223.255.255.255

D类地址:组播地址

不分网络地址和主机地址,第一字节的前四位固定为1110

224.0.0.1-----239.255.255.255

注意几点:

1、192.168.1.255为广播地址,任何主机都是不能使用的。

2、每一个网络地址都能组成一个小型的局域网。

3、127.0.0.1测试tcp,udp网络时使用的内部回环网络

几种常见的网络分包格式

一、 tcp数据包格式:



Ethernet header:网络物理接口层(存放了网卡的MAC地址,共48位)

Ip header:网络层,存放了目标主机的ip地址,源主机的ip地址

TCP:传输层,存放了目标主机的port号和源主机的port号。这层确定传输是否可靠

Ethernet trailer:对传输的数据进行CRC校验

发送过程:应用层—>加个应用层头-à加个tcp头---》加个ip头---》加个ethernet 头(指定mac地址)---》最后对数据进行CRC校验。

接收过程:反方向砍掉各种各样的头,先进行CRC校验---》验证MAC地址,如果匹配,则将其砍掉---》验证主机ip地址、匹配,将其砍掉----》验证tcp的port,匹配将其砍掉---》最后只剩下数据了。

Accept的第二个参数填放了目标主机的ip和端口号。

二、 udp数据包格式:



跟tcp差不多,只是传输层的协议改成了udp,面向不链接。

Sendto的倒数第二个参数填放了目标主机的ip及端口等信息

几种常见的网络分包格式

三、 广播udp数据包格式:



与udp数据包有两个地方的区别:

1、 分别是mac地址为FF :FF: FF: FF:FF:FF整个四十八位全为1

2、 在网络层目标ip地址为:192.168.1.255

四、 组播udp数据包格式:



与广播udp数据包格式的区别主要在mac:组播数据包的mac目标地址为:[0 00500]前面为高25位,低23位为目标ip的低23位,这样的话,只要目标ip没有加入到组播,mac地址首先就无法匹配,这样大大提高了数据的传输效率,不用每次都需要匹配到udp 的传输层才能判断出是否要发送数据。

UDP的通信的范例
编程步骤:
服务器(收数据):
1、创建socket(socket())得到socketfd
2、绑定本机ip(bind())一般绑定宏ip
3、先接受数据得到对方的ip和port(recvfrom())
4、发送数据(sendto())
5、关闭socketfd(close())

(发送数据)
1、创建socket(socket())得到socketfd
2、初始化对方主机的ip和端口号
3、发送数据(sendto)倒数第二参数为对方的ip和port号
4、接受数据
5、关闭socket(close())

服务器:
#include<stdio.h>
#include<netinet/in.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<pthread.h>
#include<strings.h>

int main()
{    int socketfd = socket(AF_INET,SOCK_DGRAM,0);//、、、、1.创建udp套接字socket得到socketfd
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);
//此处可以使用宏ip(=htonl(INADDR_ANY))该宏ip为一个整型数z转化为二进制L==long
saddr.sin_addr.s_addr = inet_addr("192.168.193.2");
if(bind(socketfd,(struct sockaddr*)&saddr,sizeof(struct sockaddr_in))<0)//2、、、、、、绑定本机的ip地址
perror("bind() error!\n");

struct sockaddr_in caddr;
int s = sizeof(struct sockaddr);
char buf[20],buf1[20];
int n;
while(1)//、、、、、、、、、、、、、、、、、、、、、、、、3.收发数据
{
bzero(buf,20);
//scanf("%s",buf);
if(n = recvfrom(socketfd,buf,20,0,(struct sockaddr *)&caddr,&s)<0)//recvfrom的倒数第二个参数为对方的ip和端口号,recvfrom函数自动获取,因此sendto中的地址就填该结构体。
perror("send() error!\n");
printf("%s",buf);
fgets(buf1,20,stdin);
sendto(socketfd,buf1,strlen(buf),0,(struct sockaddr *)&caddr,s);
}
close(socketfd);//、、、、、、、、、、4.关闭套接字socketfd

}
客户端:
#include<stdio.h>
#include<netinet/in.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include<pthread.h>
#include<strings.h>

int main()
{
int socketfd = socket(AF_INET,SOCK_DGRAM,0);//、、、、、、、1.创建udp套接字得到socketfd文件描述符
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);
saddr.sin_addr.s_addr = inet_addr("192.168.193.2");//、、、2.初始化结构体sockaddr_in 目标主机的ip,sendto的倒数第二个参数

struct sockaddr_in caddr;
int s = sizeof(struct sockaddr);
char buf[20],buf1[20];
int n;
while(1)//、、、、3.发送接收数据.
{
//bzero(buf,20);
fgets(buf,20,stdin);
if(n = sendto(socketfd,buf,strlen(buf),0,(struct sockaddr *)&saddr,s)<0)
perror("recv() error!\n");
//    printf("%d\n",n);
bzero(buf1,20);
recvfrom(socketfd,buf1,20,0,(struct sockaddr *)&caddr,&s);
printf("%s",buf1);
}
close(socketfd);//、、、4.关闭socketfd

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: