一、基础协议部分
(1)OSI七层模型:物、数、网、传、会、表、应。
若精简为四层模型,则为网、网、传、应。
四层模型中,每一层对应的协议如下:
应用层:http、ssh、ftp
传输层:tcp、udp
网络层:ip、ICMP、IGMP
网络接口层:以太网帧协议、ARP
(2)c/s模型(客户端-服务端模型)
优点:可缓存大量数据、可自己开发相应的传输协议、速度快
缺点:安全性较低、开发量较大、不可跨平台使用
b/s模型(浏览器-服务端模型)
优点:安全性高、开发量较小、可跨平台使用
缺点:不可缓存大量数据、严格遵守http协议、速度较慢
(3)网络传输流程:数据在没有进行封装以前是不能够进行传输的
封装的过程是:应用层-传输层-网络层-网络会话层
ARP协议:通过ip地址来确定mac地址
以太网帧协议:根据mac地址完成数据的传输
(4)ip协议:分为ipv4协议和ipv6协议,
源ip:32位4字节 目的ip:32位4字节
TTL:设置数据包在路由节点中的跳转上限,每经过一个路由节点ttl值减一,当ttl减为0时的路由节点负责将数据包丢弃。用这样的方式防止数据在路由节点中拥堵
ip地址:在网络环境中,标识唯一一台主机
端口号:在网络的主机上,标识一个进程,端口号最大为65535,http的端口号是8080
ip地址加端口号:在网络环境中,标识唯一一个进程
(5)socket(套接字)
一个套接字对应一个文件描述符
在通信过程中,套接字一定是成对出现的
网络字节序:说的其实就是大端格式。
点分十进制:拿最常见的ip地址举例,192.168.1.16这就是一个点分十进制的ip地址
二、Socket编程
(1)服务端部分代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<pthread.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<ctype.h>
#include <string.h>
#define SEVER_PORT 9527
#define SEVER_IP "192.168.31.102"
#define CMD_REGISTER 101
#define CMD_GETINFO 102
#define CMD_CHECK 103
#define STAT_OK 30
#define STAT_ERR 40
typedef struct student{
char name[];
int score;
int cmd;
int stat;
}info;
int main(int argc,char* argv[])
{
int fd1,ret1,ret2,fd2,count,ret3;
char recvbuf[100]={0};
char sendbuf[100]={0};
struct sockaddr_in sever_addr;
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
sever_addr.sin_family = AF_INET;
sever_addr.sin_port = htons(SEVER_PORT);
sever_addr.sin_addr.s_addr = inet_addr(SEVER_IP);
fd1 = socket(AF_INET,SOCK_STREAM,0);
printf("fd1 value is %d\n",fd1);
ret1 = bind(fd1,(struct sockaddr*)&sever_addr,sizeof(sever_addr));
printf("ret1 value is %d\n",ret1);
ret2 = listen(fd1,128);
printf("ret2 value is %d\n",ret2);
fd2 = accept(fd1,(struct sockaddr*)&client_addr,&client_addr_len);
printf("fd2 value is %d\n",fd2);
while(1){
info st1;
count = recv(fd2,&st1,sizeof(st1),0);
printf("客户端发过来的信息接收成功%d\n",count);
if(st1.cmd == CMD_REGISTER)
{
printf("学生要注册信息\n");
printf("学生姓名是%s,学生分数是%d\n",st1.name,st1.score);
st1.stat = STAT_OK;
ret3 = send(fd2,&st1,sizeof(info),0);
}
}
}
(2)客户端部分代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<pthread.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<ctype.h>
#include <string.h>
#define SEVER_PORT 9527
#define SEVER_IP "192.168.31.102"
#define CMD_REGISTER 101
#define CMD_GETINFO 102
#define CMD_CHECK 103
#define STAT_OK 30
#define STAT_ERR 40
typedef struct student{
char name[20];
int score;
int cmd;
int stat;
}info;
int main()
{
int fd,ret,count,ret1;
char sendbuf[100]={0};
struct sockaddr_in sever_addr;
sever_addr.sin_family = AF_INET;
sever_addr.sin_port = htons(SEVER_PORT);
sever_addr.sin_addr.s_addr = inet_addr(SEVER_IP);
fd = socket(AF_INET,SOCK_STREAM,0);
printf("socket success fd is %d\n",fd);
ret = connect(fd,(struct sockaddr*)&sever_addr,sizeof(sever_addr));
printf("connect success ret is %d\n",ret);
// strcpy(sendbuf,"hello world");
// count = send(fd,sendbuf,strlen(sendbuf),0);
// printf("send %d byte\n",count);
while(1)
{
info st;
printf("请输入学生的姓名\n");
scanf("%s",st.name);
printf("请输入学生的成绩\n");
scanf("%d",&st.score);
st.cmd = CMD_REGISTER;
count = send(fd,&st,sizeof(info),0);
printf("输入了一个学生的信息%d\n",count);
memset(&st,0,sizeof(info));
ret = recv(fd,&st,sizeof(info),0);
if(STAT_OK == st.stat)
{
printf("学生信息注册成功\n");
}
else
{
printf("学生信息注册失败\n");
}
}
}