1、网络编程的概念与模式
① 网络编程的本质
使用操作系统提供的接口函数,使得应用程序具备收发网络数据的能力。
- 网络接口在代码层面是操作系统提供的函数
- 应用程序通过网络接口使用操作系统的联网能力
② 网络编程核心概念
- 协议:为进行数据通信而预定义的数据规则
- 地址:网络通信中的用于标识设备的整数值
- 端口号:
- 设备为收发数据而指定的数值,用于标识具体连接
- 可理解为:设备中用于网络通信的数据通道
- 角色
③ 网络知识充电站
- 网址就是IP地址吗? URL是什么,域名又是什么?
- 网址不是IP地址(设备地址),是网络信息资源的地址(如:具体网页的地址),即:URL
- 域名是IP地址的别名,多个域名可指向同一个IP地址( 域名和IP是映射关系; 通过DNS查询到IP,域名==>DNS==>IP地址 )
- 协议一定是看不懂的二进制数据吗?
- 协议是一种约定,即:预先定义的规则
- 协议可以基于文本定义,也可以基于二进制定义
- 小端系统
- 采用小端模式(little-endian)的系统,即:数据低字节放在内存低地址中
- 大端系统
- 采用大端模式(big-endian)的系统,即:数据低字节放在内存高地址中
- 网络字节序
- 网络字节顺序采用大端模式,所以:在小端系统中需要做字节序转换
④ 网络编程模式
⑤ 初探网络编程接口
#include <sys/types.h>
#include <sys/socket.h>
⑥ 编写网络实验
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define JR_SUCCESS 0
#define JR_FAILURE -1
int main()
{
int sock = 0;
struct sockaddr_in addr = {0};
char* tosend = "GET /index.html HTTP/1.1\nHOST: www.dt4sw.com\nUser-Agent: TEST\nConnection: close\n\n";
int len = 0;
char buf[128] = {0};
int r = 0;
// 准备网络连接 申请系统资源
sock = socket(PF_INET, SOCK_STREAM, 0);
if( sock == JR_FAILURE )
{
printf("socket error\n");
return JR_FAILURE;
}
// 连接远程设备
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("47.99.217.175"); // inet_addr 字符串转为符合网络字节序的整型
addr.sin_port = htons(80); // htons 本机字节序转换为网络字节序
if( connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == JR_FAILURE )
{
printf("connect error\n");
return JR_FAILURE;
}
printf("connect success\n");
len = send(sock, tosend, strlen(tosend), 0);
printf("send bytes = %d\n", len);
len = 0;
do
{
int i = 0;
r = recv(sock, buf, sizeof(buf), 0);
if( r > 0 )
{
len += r;
}
for(i=0; i<r; i++)
{
printf("%c", buf[i]);
}
} while ( r > 0 );
printf("\n");
printf("recv bytes = %d\n", len);
// 关闭连接
close(sock);
return 0;
}
2、服务端编程初体验
① 客户端/服务端 编程模式 (c/s模型)
- 服务端长期暴露于网络,并等待客户端连接
- 客户端发起连接动作,并等待服务端回应
- 特点:
- 服务端无法主动连接客户端
- 客户端只能按照预定义的方式连接服务端
② 服务端编程模式
- 准备网络连接
- 绑定端口
- 进入端口监听状态
- 等待连接(当连接上时,返回与客户端通信的socket)
③ 服务端核心工作:绑定&监听&接收
1. 绑定
int bind( int sock, struct sockaddr* addr,socklen_t addrlen );
2. 监听
int listen( int sock, int backlog ); // backlog:队列长度,服务几个客户端
3. 接收(返回与客户端进行通信的socket)
int accept( int sock, struct sockaddr* addr,socklen_t* addrlen );// 与客户端通信的socket
④ 深度剖析服务端
- 服务端socket只用于接收连接,不进行实际通信
- 当接收到连接时,accept()函数返回与客户端通信的socket
- 服务端socket产生用于通信的客户端socket
⑤ 深入理解 socket()函数
- socket()是什么? 本质是提供通信能力。
- socket()返回的又是什么?
- socket()还能做什么?
- socket()可提供不同类型的通信功能(本地进程间通信)
⑥ 客户端/服务端 编程的核心模式
- 服务端长时间运行(死循环)接收客户端请求
- 客户端连接后向服务端发送请求(协议数据)
⑦ 客户端/服务端 编程实验
- 服务端持续监听客户端连接
- 服务端被连接后echo客户端数据(echo:返回相同数据)
- 服务端接收到quit后断开连接
- 客户端接收用户输入并发送到服务端
⑧ 编程实验 :客户端/服务端 编程实验
client
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int sock = 0;
struct sockaddr_in addr = {0};
int len = 0;
char buf[128] = {0};
char input[32] = {0};
int r = 0;
sock = socket(PF_INET, SOCK_STREAM, 0);
if( sock == -1 )
{
printf("socket error\n");
return -1;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("39.99.145.220");
addr.sin_port = htons(8888);
if( connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1 )
{
printf("connect error\n");
return -1;
}
printf("connect success\n");
while( 1 )
{
printf("Input: ");
scanf("%s", input);
len = send(sock, input, strlen(input) + 1, 0);
r = recv(sock, buf, sizeof(buf), 0);
if( r > 0 )
{
printf("Receive: %s\n", buf);
}
else
{
break;
}
}
close(sock);
return 0;
}
server
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
int server = 0;
struct sockaddr_in saddr = {0};
int client = 0;
struct sockaddr_in caddr = {0};
socklen_t asize = 0;
int len = 0;
char buf[32] = {0};
int r = 0;
server = socket(PF_INET, SOCK_STREAM, 0);
if( server == -1 )
{
printf("server socket error\n");
return -1;
}
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(8888);
if( bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1 )
{
printf("server bind error\n");
return -1;
}
if( listen(server, 1) == -1 )
{
printf("server listen error\n");
return -1;
}
printf("server start success\n");
while( 1 )
{
asize = sizeof(caddr);
client = accept(server, (struct sockaddr*)&caddr, &asize);
if( client == -1 )
{
printf("client accept error\n");
return -1;
}
printf("client: %d\n", client);
do
{
r = recv(client, buf, sizeof(buf), 0);
if( r > 0 )
{
printf("Receive: %s\n", buf);
if( strcmp(buf, "quit") != 0 )
{
len = send(client, buf, r, 0);
}
else
{
break;
}
}
} while ( r > 0 );
close(client);
}
close(server);
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)