项目名称 | 【苏嵌实训-嵌入式 linux C 第 8天】 |
---|---|
今日进度以及任务 | 嵌入式Linux C网络编程 |
本日任务完成情况 | 笔记见表格下方。 |
本日开发中出现的问题汇总 | 无 |
本日未解决问题 | 无 |
本日开发收获 | 学习了网络的基础知识以及网络编程代码实现 |
其他 | 无 |
笔记:
一、网络基础知识
1、为什么需要网络通信?
<进程间通信解决的事本机内通信>
<网络通信解决的是任意不同机器通信>
2、实现网络通信需要哪些支持?
1)通信设备
网卡:PC机自带
路由器、交换机
光纤、电缆、基站
2)通信协议
操作系统自带协议栈:(Linux的特点:丰富的网络协议)
裸机开发需要独立的协议栈
3)简单网络通信只需要学会使用系统API
3、OSI七层网络模型、Linux四层网络模型
4、端口号的作用:
通过IP地址找到指定的机器,通过端口号可以找到机器上与之通信的应用软件。
<源端口号和目的端口号要保持一致>
三次握手:
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手
字节序:
大端字节序: 低字节放在高地址,高字节放在低地址
小端字节序: 低字节放在低地址,高字节放在高地址
二、网络编程代码实现
TCP的服务端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 33333
int main()
{
int sockfd;
int cfd;
int c_len;
char buffer[1024];
struct sockaddr_in addr;
struct sockaddr_in c_addr;
//创建套接字:socket函数
sockfd = socket(AF_INET,SOCK_STREAM,0);//IPV4,TCP
if(sockfd == -1)
{
perror("socket create error!");
exit(1);
}
printf("socket success!\n");
//先关客户端,再关服务器,否则会出现无法绑定的问题
int opt = 1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
//以上为无法绑定解决
//给套接字绑定IP地址和端口号:bind函数
bzero(&addr,sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(PORT);//字节序转化//转成本地的
addr.sin_addr.s_addr = inet_addr("192.168.137.129");//将网络地址转化为二进制数
if(bind(sockfd,(struct sockaddr *)(&addr),sizeof(struct sockaddr_in)) < 0)
{
perror("bind error!");
exit(1);
}
printf("bind success!\n");
//将套接字文件描述符,从主动变为被动文件描述符(做监听准备):listen函数
if(listen(sockfd,3) < 0)
{
perror("listen error!");
exit(1);
}
printf("listen success!\n");
//被动监听客户的连接并响应:accept函数
while(1)
{
memset(buffer,0,sizeof(buffer));
bzero(&c_addr,sizeof(struct sockaddr_in));
c_len = sizeof(struct sockaddr_in);
cfd = accept(sockfd,(struct sockaddr *)(&c_addr),&c_len);
printf("accept···········!");
if(cfd == -1)
{
perror("accept error!");
exit(1);
}
printf("accept success!\n");
printf("port = %d,ip = %s\n",ntohs(c_addr.sin_port),inet_ntoa(c_addr.sin_addr));
read(cfd,buffer,sizeof(buffer));
printf("recv = %s\n",buffer);
usleep(2);//毫秒级休眠
write(cfd,buffer,strlen(buffer));
}
//先关客户端,再关服务器,否则会出现无法绑定的问题
return 0;
}
TCP的客户端:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 33333
int main()
{
int sockfd;
struct sockaddr_in s_addr;
//创建套接字
sockfd = socket(AF_INET,SOCK_STREAM,0);//IPV4,TCP
if(sockfd == -1)
{
perror("socket create error!");
exit(1);
}
printf("socket success!\n");
//连接
bzero(&s_addr,sizeof(struct sockaddr_in));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(PORT);
s_addr.sin_addr.s_addr = inet_addr("192.168.137.129");
if(connect(sockfd,(struct sockaddr *)(&s_addr),sizeof(struct sockaddr_in)) < 0)
{
perror("connect error!");
exit(1);
}
printf("connect success!\n");
write(sockfd,"hello world",12);
char buffer[1024];
read(sockfd,buffer,sizeof(buffer));
printf("recv server:%s",buffer);
return 0;
}