下面这个案例是我用C在ubtuntu上面写的网络编程案例。
2. 网络编程
(1)OSI七层模型理想化
应用层:app,应用程序。
表示层:对数据进行加工。
会话层:建立会话。(比如电脑之间通信,就会建立会话,跟不同电脑通信,都会建立不同的会话)。
传输层:保证数据能够可靠传输。
网络层 :路由选择 (可以实现不同局域网之间的互联)。
数据链路层 :局域网之间的数据传输。
物理层:决定传输介质。
(2) TCP/IP四层模型(TCP/IP协议簇)
Tcp协议:用来实现数据的可靠传输。
UDP:传输数据不可靠。
IP协议:对于不同的局域网之间互联的协议。
应用层:对应理想化模型的应用层,表示层,会话层。
//http协议:发出请求的协议。
//dns协议,域名解析协议。
tftp:文件传输协议
传输层:TCP/UDP
网络层:IP
网络接口和物理层://以太网
(3) 协议:通信规则。目的:能够进行有目的的通信。
套接字:(socket)提供网络通信的编程接口。是一个特殊的文件(s)。
套接字位于传输层和应用层之间。
IP地址:软件层次或者网络里主机的唯一标识。192.168.1.45:前三个一样表示在一个局域网。
2~254我们可以使用,0,1,255比较特殊。
端口号:区分同一台电脑上的不同的进程,进程是能够进行网络通信的进程。
端口号就是确定是哪个端口在通信
范围:0~65535,1024以后就可以使用了。
字节序:就是大于一个字节类型的数据在内存中存放顺序。
Big-Endian:大端:高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
Little-Endian:小端:低位字节排放在内存的低地址端,高位字节排放在内存的高地址段。
MAC地址:全世界唯一的地址
(4) TCP和UDP区别:
TCP:可靠,有连接。
UDP:无连接,不可靠。
TCP的有连接的是通过三次握手和四次挥手来实现的。
客户端:请求服务的一方,主动。
服务器:提供服务的一方,被动。
TCP三次握手:
1、客户端向服务器发出连接请求。
2、服务器应答,并且向客户端发出连接请求。
3、客户端应答
TCP四次挥手:
1、客户端向服务器发出断开请求。
2、服务器应答。
3、服务器向客户端发出断开连接请求。
4、客户端应答。
(5)搭建模型
服务器创建流程:
1、创建一个套接字(主动)。Socket
2、绑定IP地址和端口号。bind
3、 创建监听队列使套接字变成被动的套接字。listen
4、等待和客户端连接。Accept
5、通信。Read/write recv/send
6、关闭套接字。Close
服务器代码:
1.socket
#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain,int type,int protocol);
参数1:地址族
参数2:套接字类型:(TCP)SOCK_STREAM(流式),(UDP)SOCK_DGRAM (数据报),SOCK_RAW。
参数3:一般为0,代表自动匹配协议。
返回值:创建成功返回套接字。
3.Bind
#include<sys/types.h>
#include<sys/socket.h>
Int bind(int sockfd,const struct sockaddr*addr,socklen_t addrlen);
参数1:创建成功的套接字。
参数2:要绑定的ip和端口的信息。
参数3:ip和端口填充的结构体的大小。
返回值:绑定成功返回0,失败返回-1。
Struct socketaddr{
Sa_family_t sa_family;
Char sa_data[14];
}
Struct sockaddr_in{
U_short sin_family; //地址族
U_short sin_port; //端口号 11023被占用,102449151
Struct in_addr sin_addr;//ipv4地址
Char sin_zero[8];//填充位
};
#include<arpa/inet.h>
3、listen
#include<sys/types.h>
#include<sys/socket.h>
Int listen(int sockfd,int backlog);
参数1:套接字
参数2:监听的个数
参数3:监听成功返回0,失败返回-1.
4.Accept
#include<sys/types.h>
#include<sys/socket.h>
int accept(sockfd,struct sockaddr addr,socklen_taddrlen);
返回值:连接成功返回套接字,这个套接字是用来进行数据收发,连接失败返回-1。
5、send/recv
#include<sys/types.h>
#include<sys/socket .h>
Ssize_t recv(int socketfd,void *buf,size_t len,int flags);
参数1:accept函数的返回值。
参数2:数据缓存区 哟隔开保存收到的数据。
参数3:一次性接收多大的数据。
参数4:通常为0,阻塞模式接收数据。
6、Send
#include<sys/types.h>
#include<sys/socket.h>
Ssize_t send(int sockfd,const void *buf,size_t len,int flags);
1.参数1:accept函数的返回值。
2.参数2:数据缓存区,保存着要发送的数据。
3.一次性发送多大的数据。
4.通常为0 阻塞模式发数据。
返回值:成功返回实际发送字节数,失败返回-1.
客户端的流程:
1、创建一个套接字(主动)。
2、向服务器发出连接请求。
3、通信。
4、关闭套接字。
服务器端:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<strings.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netinet/in.h>
int main()
{
int sockFd = socket(AF_INET,SOCK_STREAM,0);
if(sockFd < 0)
{
printf("socket failed!");
return -1;
}
printf("socket success!\n");
struct sockaddr_in serAddr;
memset(&serAddr,0,sizeof(serAddr));
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(10086);
serAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int ret = bind(sockFd,(struct sockaddr *)&serAddr,sizeof(serAddr));
if(ret < 0)
{
printf("bind failed!\n");
close(sockFd);
return -1;
}
printf("bind success!\n");
ret = listen(sockFd,5);
if(ret < 0)
{
printf("listen failed!\n");
close(sockFd);
return -1;
}
printf("listen success!\n");
struct sockaddr_in stClient;
memset(&stClient,0,sizeof(stClient));
socklen_t len = sizeof(stClient);
while(1){
int iClient = accept(sockFd,(struct sockaddr *)&stClient,&len);
if(iClient < 0)
{
printf("accept failed!\n");
close(sockFd);
return -1;
}
printf("accept sucess!\n");
char buf[1024] = {0};
while(1)
{
ret = recv(iClient,buf,sizeof(buf),0);
if (ret > 0)
{
printf("recv ok!\n");
printf("%s\n",buf);
}
else if(ret < 0)
{
printf("recv error!\n");
close(iClient);
close(sockFd);
return -1;
}
else
{
printf("read over!");
break;
}
ret = send(iClient,buf,strlen(buf),0);
if(ret < 0)
{
printf("send error!");
close(sockFd);
close(iClient);
return -1;
}
printf("send ok!\n");
}
close(iClient);
}
close(sockFd);
return 0;
}
客户端:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<strings.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
int main()
{
int sockFd = socket(AF_INET,SOCK_STREAM,0);
if(sockFd <0)
{
printf("socket failed!\n");
return -1;
}
printf("socket success!\n");
struct sockaddr_in stServer;
memset(&stServer,0,sizeof(stServer));
stServer.sin_family = AF_INET;
stServer.sin_port = htons(10086);
stServer.sin_addr.s_addr = inet_addr("127.0.0.1");
int ret = connect(sockFd,(struct sockaddr *)&stServer,sizeof(stServer));
if(ret <0)
{
printf("connect failed!\n");
close(sockFd);
return -1;
}
printf("connect failed\n");
char buf[1024] = {0};
char recv_buf[1024] = {0};
while(1)
{
memset(buf,0,sizeof(buf));
printf("input:");
fgets(buf,1023,stdin);
if((strcmp(buf,"quit\n"))==0)
{
printf("Exit!\n");
break;
}
}
ret = send(sockFd,buf,strlen(buf),0);
if(ret<0)
{
printf("send failed!\n");
close(sockFd);
return -1;
}
printf("send ok!\n");
memset(recv_buf,0,sizeof(recv_buf));
ret = recv(sockFd,recv_buf,sizeof(recv_buf),0);
if(ret<0)
{
printf("recv error!\n");
close(sockFd);
return -1;
}
printf("recv ok! recv:%s\n",recv_buf);
}
close(sockFd);
return 0;
}
运行结果:
这是我以前用Python写的网络编程的案例,大家可以看看
https://blog.csdn.net/qq_44176343/article/details/113807144?spm=1001.2014.3001.5502
Python网络编程案例
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)