主机字节序列和网络字节序列,套接字,tcp服务端代码,客户端代码

一,主机字节序列和网络字节序列

1,主机字节序列

端口号:标识一个进程;
协议:tcp http IP udp
主机字节序列分为大端字节序和小端字节序,不同的主机采用的字节序列可能不同。大
端字节序是指一个整数的高位字节存储在内存的低地址处,低位字节存储在内存的高地址处。小端字节序则是指整数的高位字节存储在内存的高地址处,而低位字节则存储在内存的低地址处。

2,网络字节序列

在两台使用不同字节序的主机之间传递数据时,可能会出现冲突。所以,在将数
据发送到网络时规定整形数据使用大端字节序,所以也把大端字节序称为网络字节序列。对方接收到数据后,可以根据自己的字节序进行转换。

Linux 系统下 主机字节序和网络字节序之间的转换

在这里插入图片描述

3,端口号

3.1端口号(port)是传输层协议的内容

端口号是一个32位的整数;
端口号用来标识一个进程, 告诉操作系统, 当前的这个数据要交给哪一个进程来处理;
IP地址 + 端口号能够标识网络上的某一台主机的某一个进程;
一个端口号只能被一个进程占用.

源端口号和目的端口号:
传输层协议(TCP和UDP)的数据段中有两个端口号, 分别叫做源端口号和目的端口号. 
就是在描述 "数据是谁发的, 要发给谁";

3.2理解“端口号”和“进程ID”

pid 表示唯一一个进程;
端口号也是唯一表示一个进程.

**一个进程可以绑定多个端口号; 但是一个端口号不能被多个进程绑定;**

二,套接字

引出套接字

我们知道网络应用通信(应用层)的实质是进程之间的通信
如:两个主机(电脑)上的qq是通过电脑运行qq这个程序(进程)通过网络传输数据进行聊天

根据五层理论模型,应用层接收的是传输层的数据。

那么问题来了😁
1.传输层是直接连接的应用层嘛
2.一台主机上有很多进程,如何把传输层的数据发送到特定进程

这就引出了今天的主角——套接字(套接字API)在这里插入图片描述

套接字的功能

从上图的可以看出,传输层真正连接的是套接字,通过套接字将数据发送给特定的进程

传输层如何标识套接字
通过ip地址+端口号标识套接字,套接字绑定了主机端口号
ip地址对应相应主机
进程监控相应端口

注意:一台主机上一个端口号只能对应一个进程,一个进程可以监控多个端口

所以网上给的定义:套接字=ip地址+端口号
ip地址及端口号会封装到传输层的数据(报文)中

套接字就像我们的手机它具备这样的功能,能够通过网络来进行数据收和发;
传输层真正连接的是套接字,通过套接字将数据发送给特定的进程

传输层如何标识套接字?
通过ip地址+端口号标识套接字,套接字绑定了主机端口号
ip地址对应相应主机
进程监控相应端口
创建套接字就相当于两个人各自买个手机才能实现通讯;
为什么第一步要创建套接字
创建套接字它能通过网络进行收发;
s服务端地址,c客户端地址(别人链接我,我要给对方回复数据)

套接字地址

三,服务端代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<unistd.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
int mian
{
int sockfd=socket(AF_INET,SOCK_STREAM,0);//创房间套接字它能通过网络进行数据的收发;
                     ipv4  使用tcp
assert(sockfd!=-1);socketfd文件描述符;
struct sockaddr_in saddr,caddr; saddr代表服务器端口地址,caddr代表客户端的地址;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family=AF_INET;地址家族
saddr.sin_port=htons(6000);//主机字节序转网络字节序;将6000这个端口转化为网络字节序列
saddr.sin_addr.s_addr=inet_addr("127.0.0.1");将字符串(ip地址)转化为无符号整形
                                 ifconfig命令找到的
//指定套接字IP,port绑定;
int res=bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//指定这个套接字使用的IP端口即将IP地址与套接字绑定
assert(res!=-1);
res=listen(sockfd,5);//监听队列的大小;
assert(res!=-1);
while(1)
{
int len=sizeof(caddr);
//c是连接那你                                                                                                                                                                                                                                                                                                          套接字,sockfd是监听套接字;
int c=accept(sockfd,(struct sockaddr*)&caddr,&len);接受链接
if(c<0)
{
continue;
}
printf("accept c=%d\n",c);
char buff[128]={0};
int num=recv(c,buff,127,0);//接收数据;
printf("buff=%s,num=%d\n",buff,num);
send(c,"ok",2,0);//给客户端发送数据;
close(c);//完成之后关闭这个链接;
}
close(sockfd);
exit(0);
}

四,客户端代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<assert.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
int mian()
{
int sockfd=socket(AF_INET,SOCK_STREAM,0);//创建套接字
assert(sockfd!=-1);
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("127.0.0.1");
//发起链接
int res=connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
assert(res!=-1);
printf("input:\n");
char buff[128]={};
fgets(buff,128,stdin);
//给服务器发送数据;
send(sockfd,buff,strlen(buff),0);
memset(buff,0,128);
//接受数据据;
recv(sockfd,buff,strlen(buff),0);
printf("buff=%s\n",buff);
//关闭链接
close(sockfd);
exit(0);

}

在这里插入图片描述
在这里插入图片描述
转换网络字节序
在这里插入图片描述
在这里插入图片描述
测试IP
将端口设置到套接字上,连接可能会失败(端口号已经被用,或者IP号输错)
25:17
监听套接字与链接套接字
每次的一个c代表的是一个客户端;

服务器端的端口需要声明
客户端端口不需要声明
顺序:必须先启动服务器端后启动客户端;
在这里插入图片描述
有没有可能发了一次数据还没接收又发了一次,直接接收两次的数据

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值