目录
1.4网络字节序、IP地址类型转换、数据接收与发送函数、popen函数
一、网络编程套接字
1、一些概念
1.1源IP地址和目的IP地址
源IP地址:发送主机的IP地址。
目的IP地址:接收主机的IP地址。
1.2端口号port
端口号是传输层的协议的内容。
既然网络通信的双方本质都是进程,为什么不直接使用pid来标定网络通信双方通信进程的唯一性,而是使用端口号呢?1、解耦2、例如客户端需要找到服务器进程,因为进程每次创建销毁pid是会变的,而网络编程弄了个端口号,直接写死了是哪个进程,这样每次都能找到。
那么怎么找呢?操作系统内部维护了一张哈希表,key是端口号,value是进程PCB的地址。
1.3TCP和UDP的性质
UDP:
TCP:
1.4网络字节序、IP地址类型转换、数据接收与发送函数、popen函数
可以使用以下库函数做网络字节序和主机字节序的转换:
BYTEORDER(3)
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。
可以使用以下库函数对ip地址进行转换:
INET(3)
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);
in_addr_t inet_addr(const char *cp);//将字符串转uint32_t的同时转为网络字节序
in_addr_t inet_network(const char *cp);
char *inet_ntoa(struct in_addr in);//将32位IPv4地址(in_addr结构体)转换成点分十进制字符串形式的IP地址
struct in_addr inet_makeaddr(int net, int host);
in_addr_t inet_lnaof(struct in_addr in);
in_addr_t inet_netof(struct in_addr in);
popen函数==pipe+fork+exec*
POPEN(3)
#include <stdio.h>
FILE *popen(const char *command, const char *type);
int pclose(FILE *stream);
2、UDP套接字
UDP套接字种类及接口
2.1UDP服务器创建流程
2.2UDP客户端创建流程
相关指令及函数:
ifconfig 显示网络设备信息,找到127.0.0.1本地回环地址
ps axj | grep udpServer过滤出当前的udpServer进程
netstat -nuap//n:能显示数字的现实成数字;u:udp;a:all;p:进程
sudo netstat -nuap//n:以数字形式显示地址和端口号,不进行反向解析,a:all,u::udp,p:process ID/name,
sudo netstat -altp//l::listen,t:tcp
recvfrom
sendto
close
bzero
2.3创建socket套接字
SOCKET(2)
#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
2.4绑定套接字对应的IP地址、端口号
BIND(2)
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
2.5客户端、服务器数据的接收与发送
UDP 套接字是无连接协议,必须使用recvfrom函数接收数据,sendto函数发送数据:
RECV(2)
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
SEND(2)
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
3、TCP套接字
3.1TCP服务器创建流程
3.2TCP客户端创建流程
3.3创建socket套接字
同UDP创建套接字的方法,只不过在传参时UDP传入SOCK_DGRAM(数据报),而TCP传入SOCK_STREAM(字节流)
_sockfd=socket(AF_INET,SOCK_DGRAM,0);//UDP网络通信+数据报
_listenfd=socket(AF_INET,SOCK_STREAM,0);//TCP网络通信+字节流
3.4绑定套接字对应的IP地址、端口号
同UDP。
3.5服务器设置socket为监听状态
因为TCP是有连接的协议,需要使用listen函数将一个套接字设置为监听状态。
LISTEN(2)
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
3.6服务器获取客户端连接请求
ACCEPT(2)
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
3.7客户端发起连接请求
CONNECT(2)
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);