学习嵌入式第三十四天
文章目录
- 网络
- 1.概念
- 2.函数接口
- 3.主要协议
- 1.TCP
- 2.UDP
- 习题
网络
1.概念
- 不同主机间的进程间通信
- IP:确定主机的地址
- 端口号:用来标识一个网络通信的进程
2.函数接口
-
socket
原型:int socket(int domain, int type, int protocol); 功能:建立通信的一端 参数:domain:通信的范围,指定网络类型type:套接字类型,指定通信语义SOCK_STREAM //流式套接字SOCK_DGRAM //数据报套接字protocol:协议 返回值:成功返回文件描述符失败返回-1 Name Purpose AF_UNIX, AF_LOCAL Local communication AF_INET IPv4 Internet protocols AF_INET6 IPv6 Internet protocols AF_IPX IPX - Novell protocols AF_NETLINK Kernel user interface device AF_X25 ITU-T X.25 / ISO-8208 protocol AF_AX25 Amateur radio AX.25 protocol AF_ATMPVC Access to raw ATM PVCs AF_APPLETALK AppleTalk AF_PACKET Low level packet interface AF_ALG Interface to kernel crypto API
-
connect
原型:int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen); 功能:通过socket连接到指定的地址上 参数:sockfd:socket函数返回的文件描述符addr:网络中一个进程对应的地址addrlen:说明第二个参数的地址类型的大小 返回值:成功返回0失败返回-1 不同的通信域有不同的结构体 IPv4: struct sockaddr_in {sa_family_t sin_family; /* address family: AF_INET */in_port_t sin_port; /* port in network byte order */struct in_addr sin_addr; /* internet address */};/* Internet address. */ struct in_addr {uint32_t s_addr; /* address in network byte order */};
-
inet_addr
原型:in_addr_t inet_addr(const char *cp); 功能: 参数:cp:表示要用的ip地址的字符串 返回值;成功返回网络字节序形式的ip地址的32位数值
-
bind
原型:int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);、 功能:给socket端口号绑定一个地址信息 参数:sockfd:socket函数返回的文件描述符addr:网络中一个进程对应的地址addrlen:说明第二个参数的地址类型的大小 返回值:成功返回0失败返回-1
-
listen
原型:int listen(int sockfd, int backlog); 功能:将socketfd对应的socket设置为监听套接字 参数:sockfd sockfd的fdbacklog 等待队列的长度 返回值:成功返回0失败返回-1
-
accept
原型:int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); 功能:从监听的socket中提取连接请求,完成三次握手并连接 参数:sockfd:监听的socket的fdaddr:存放客户端的地址信息addrlen:值结果参数必须初始化位addr对应的socket大小 返回值:成功返回已经连接的新socket的fd失败返回-1
3.主要协议
1.TCP
- 特点
- 面向连接,即在进行通信之前,必须建立好一条逻辑上的通路
- 提供可靠传输,即无丢失,无失序,无差错,无重复
- 建立连接流程(三次握手)
- 向服务器请求连接
- 回复请求是否可以连接
- 向服务器回复连接建立成功
- 应用场景
- 电子邮件收发,web浏览
- 文件的传输
- 远程登陆和服务器的管理
2.UDP
- 特点
- 不提供可靠传输
- 在数据发送时,不需要建立连接
- 应用场景
- 小数据,但是对速度要求较高,实时性要求较高
- 广播,组播
- 无线网的传输
习题
1.客户端向服务器发送一条消息,客户端回复收到
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<netinet/ip.h>
#include<unistd.h>
#include<stdint.h>
#include<string.h>
#include<strings.h>int main(void){int fd;char tmp[256] = {0};fd = socket(AF_INET, SOCK_STREAM, 0);if (fd < 0) {perror("socket");return 1;}printf("fd = %d\n", fd);struct sockaddr_in seraddr;bzero(&seraddr,sizeof(seraddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = inet_addr("192.168.0.182");if(bind(fd,(const struct sockaddr *)&seraddr,sizeof(seraddr)) < 0){perror("fail to connect");return -1;} if(listen(fd,5) < 0){perror("fail to listen");return -1;}while(1){struct sockaddr_in cliaddr;bzero(&cliaddr,0);socklen_t len = sizeof(cliaddr);int connfd = accept(fd,(struct sockaddr *)&cliaddr,&len);if(connfd < 0){perror("fail to accept");return -1;}printf("----client connected----\n");char rbuf[1024] = {0};char sbuf[1024] = {0};int n = read(connfd,rbuf,sizeof(rbuf));if(n > 0){printf("recv:%s\n",rbuf);sprintf(sbuf,"server+ %s",rbuf);write(connfd,sbuf,strlen(sbuf));}close(connfd);}return 0;}
2.客户端和服务器端点对点聊天
#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<netinet/ip.h>
#include<unistd.h>
#include<stdint.h>
#include<string.h>
#include<strings.h>int main(void)
{int fd = socket(AF_INET, SOCK_STREAM, 0);if (fd < 0) {perror("socket fail");return -1;}struct sockaddr_in seraddr;bzero(&seraddr, sizeof(seraddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(50000);seraddr.sin_addr.s_addr = inet_addr("192.168.0.182");if (bind(fd, (const struct sockaddr *)&seraddr, sizeof(seraddr)) < 0) {perror("bind fail");return -1;}if (listen(fd, 5) < 0) {perror("listen fail");return -1;}struct sockaddr_in cliaddr;socklen_t len = sizeof(cliaddr);int connfd = accept(fd, (struct sockaddr *)&cliaddr, &len);if (connfd < 0) {perror("accept fail");return -1;}printf("---client connect---\n");pid_t pid = fork();if (pid < 0) {perror("fork fail");return -1;} else if (pid == 0) {// 子进程:发送消息char sbuf[1024];while (fgets(sbuf, sizeof(sbuf), stdin) != NULL) {write(connfd, sbuf, strlen(sbuf));}} else if(pid > 0) {// 父进程:接收消息char rbuf[1024];int n;memset(rbuf, 0, sizeof(rbuf));while ((n = read(connfd, rbuf, sizeof(rbuf) - 1)) > 0) {rbuf[n] = '\0';printf("client: %s\n", rbuf);}}close(connfd);close(fd);return 0;
}