TCP/ IP协议栈与SOCKET
tcp/ip
传输层
传输层及其以下的机制由内核提供,应用层由用户进程提供(socket编写 应用程序),应用 程序对通讯数据的含义进行解释,而传输层及其以下处理通讯的细节,将数据从一台计算机通过一定的路径发送到另一台计算机。应用层数据通过协议栈发到网络上时,每层协议都要加上一个数据首部(header) ,称为封装(Encapsulation)
socket
Linux网络编程API介绍
tcp
udp
Linux网络通信流程-TCP
客户端
#include <sys/types.h> // 类型定义
#include <sys/socket.h> //提供网络通信函数
#include<unistd.h> //针对系统调用的封装fork,pipe read write 等
#include<netinet/in.h> // 互联网地址族定 义数据结构sockaddr_ in
# include<arpa/inet.h> //提供IP地址转换函数
#include<stdio.h>
#include<string.h>
//服务器 B/S C/S tcp/ip
//1、创建套接字 socket
//发起连接 connect
//5、收发数据 send/recv
//6、关闭套接字 close
int main(){
//1、创建套接字 socket
int hSock = 0;
hSock = socket(
AF_INET, //协议族
SOCK_STREAM, //套接字类型
IPPROTO_TCP //协议类型
);
//发起连接 connect
printf("connect......\n");
struct sockaddr_in saddr;
inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr);//填写服务器ip地址192.168.78.130
saddr.sin_port = htons(12345); //主机字节序转换成网络字节序,服务端口
saddr.sin_family = AF_INET; //网络协议
int addrlen = sizeof(saddr); //地址大小
connect(hSock,(struct sockaddr*)&saddr,addrlen);
//5、收发数据 recv/send
char buff[1024]={};
recv( //接收客户消息,阻塞
hSock,
buff,
1024,
0
);
printf("接收到服务消息:%s\n",buff);
send(
hSock, //客户套接字
"hello server", //数据包
15, //数据长度
0 //默认0
);
//6、关闭套接字 close
close(hSock);
return 0;
}
服务端
#include <sys/types.h> // 类型定义
#include <sys/socket.h> //提供网络通信函数
#include<unistd.h> //针对系统调用的封装fork,pipe read write 等
#include<netinet/in.h> // 互联网地址族定 义数据结构sockaddr_ in
# include<arpa/inet.h> //提供IP地址转换函数
#include<stdio.h>
#include<string.h>
//服务器 B/S C/S tcp/ip
//1、创建套接字 socket
//2、绑定 bind
//3、监听 listen
//4、等待连接 accept
//5、收发数据 send/recv
//6、关闭套接字 close
int main(){
//1、创建套接字 socket
int hSock = 0;
hSock = socket(
AF_INET, //协议族
SOCK_STREAM, //套接字类型
IPPROTO_TCP //协议类型
);
//2、绑定 bind
struct sockaddr_in saddr;
inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr);//填写服务器ip地址192.168.78.130
saddr.sin_port = htons(12345); //主机字节序转换成网络字节序,服务端口
//0x12345678 => 78 56 34 12 小端
//0x12345678 => 12 34 56 78 大端
//现在的cpu都是小端,1234读到内存会变成34 12
saddr.sin_family = AF_INET; //网络协议
int addrlen = sizeof(saddr); //地址大小
bind(hSock,(struct sockaddr*)&saddr,addrlen); //绑定服务器地址
//3、监听 listen
printf("listen......\n");
listen(hSock,SOMAXCONN); //一次最多多少个客户连接上服务器
//4、等待连接 accept
struct sockaddr_in clientaddr={};
int clientsock = accept( //返回客户端套接字,之后所有和客户通讯都是通过这个套接字
hSock, //服务 器套接字
(struct sockaddr*)&clientaddr, //客户端地址
&addrlen); //地址大小
// char sipaddr[100];
char sipaddr[100];
//将数字转换成ip地址字符串]
inet_ntop(AF_INET,&clientaddr.sin_addr,sipaddr,100);
printf("有客户连接:[%s]:%d\n",sipaddr,ntohs(clientaddr.sin_port));
//5、收发数据 send/recv
char buff[1024]={"hello client!\n"};
send(
clientsock, //客户套接字
buff, //数据包
strlen(buff)+1, //数据长度
0 //默认0
);
recv( //接收客户消息,阻塞
clientsock,
buff,
1024,
0
);
printf("接收到客户 %s:%d 内容:%s\n",sipaddr,ntohs(clientaddr.sin_port),buff);
//6、关闭套接字 close
close(hSock);
close(clientsock);
return 0;
}
Linux网络通信流程-UDP
服务端
#include <sys/types.h> // 类型定义
#include <sys/socket.h> //提供网络通信函数
#include<unistd.h> //针对系统调用的封装fork,pipe read write 等
#include<netinet/in.h> // 互联网地址族定 义数据结构sockaddr_ in
# include<arpa/inet.h> //提供IP地址转换函数
#include<stdio.h>
#include<string.h>
// UDP编程
// 1.创建套接字
// 2. 绑定
// 3.接收消息
// 4. 发消息
// 5.关闭套接字
int main(){
// 1.创建套接字
int sock = socket(AF_INET,SOCK_DGRAM, IPPROTO_UDP);
// 2.綁定
struct sockaddr_in saddr;
inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr);//填写服务器ip地址192.168.78.130
saddr.sin_port = htons(12345); //主机字节序转换成网络字节序,服务端口
saddr.sin_family = AF_INET; //网络协议
int addrlen = sizeof(saddr); //地址大小
bind(sock,(struct sockaddr*)&saddr,addrlen);
printf("wait client connect ...");
// 3.接收消息
char buff[1024] = {};
struct sockaddr_in clientaddr = {}; //客户地址
recvfrom(
sock, //套接字
buff, //缓冲区
1024, //缓冲区大小
0, //标志,默认0
(struct sockaddr*)&clientaddr, //接收客户地址,之后用这个地址给客户发消息
&addrlen //地址长度
);
char sipaddr[100];
//将数字转换成ip地址字符串]
inet_ntop(AF_INET,&clientaddr.sin_addr,sipaddr,100);
printf("有客户连接:[%s]:%d 内容是:%s\n",sipaddr,ntohs(clientaddr.sin_port),buff);
// 4. 发消息
sendto(
sock,
"hello 客户端!",
18,
0,
(struct sockaddr*)&clientaddr,
addrlen
);
// 5.关闭套接字
close(sock);
}
客户端
#include <sys/types.h> // 类型定义
#include <sys/socket.h> //提供网络通信函数
#include<unistd.h> //针对系统调用的封装fork,pipe read write 等
#include<netinet/in.h> // 互联网地址族定 义数据结构sockaddr_ in
# include<arpa/inet.h> //提供IP地址转换函数
#include<stdio.h>
#include<string.h>
// UDP编程
// 1.创建套接字
// 2.发消息
// 3.接收消息
// 5.关闭套接字
int main(){
// 1.创建套接字
int sock = socket(AF_INET,SOCK_DGRAM, IPPROTO_UDP);
// 2.发消息
struct sockaddr_in saddr;
inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr);//填写服务器ip地址192.168.78.130
saddr.sin_port = htons(12345); //主机字节序转换成网络字节序,服务端口
saddr.sin_family = AF_INET; //网络协议
int addrlen = sizeof(saddr); //地址大小
//发消息给服务端
sendto(
sock,
"hello 服务器!",
18,
0,
(struct sockaddr*)&saddr,
addrlen
);
printf("发送成功!\n");
// 3.接收消息
char buff[1024] = {};
recvfrom(
sock, //套接字
buff, //缓冲区
1024, //缓冲区大小
0, //标志,默认0
(struct sockaddr*)&saddr, //接收服务端地址
&addrlen //地址长度
);
printf("接到服务断消息:%s\n",buff);
// 5.关闭套接字
close(sock);
}