C语言笔记-25-网络-TCP网络编程
前言
自学笔记,没有历史知识铺垫(省略百度部分)C语言笔记-25-网络-TCP网络编程
一、TCP编程模型概括
服务器端编程模型
socket()
创建socket设备,获取该设备的文件描述符 sfdbind()
将sfd与本地ip、端口绑定listen()
设置sfd为被动状态,当客户端请求到达时,将请求存放到sfd设备的未决连接队列中accept()
从sfd设备未决连接队列中取出请求,返回该请求的连接描述符read()
使用连接描述符,获取请求信息do Some...
处理请求信息write()
将处理结果通过连接描述符返回给请求客户端close()
关闭连接描述符,结束通讯
客户端编程模型
socket()
创建socket设备,获取该设备文件描述符 cfdconnect()
使用cfd向服务器端发起连接write()
向服务器发送信息read()
阻塞等待服务器响应do Some...
处理服务器响应信息close()
关闭本次连接,结束通讯
二、inet工具
htonl
在主机和网络字节顺序之间转换值,对齐时使用,如输入ip、端口时
h
代表 host
to
– 转换至
n
代表 net
l
代表long
s
代表short
#include <arpa/inet.h>
uint64_t htonll(uint64_t hostlonglong);
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint64_t ntohll(uint64_t netlonglong);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
inet_pton
将字符串地址与二进制网络地址相互转化
#include <arpa/inet.h>
// 将字符串地址转为二进制网络地址
int inet_pton(int af, const char * restrict src, void * restrict dst);
// 将二进制网络地址转为字符串地址
const char * inet_ntop(int af, const void * restrict src, char * restrict dst, socklen_t size);
三、TCP编程模型代码
TCP服务端
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
printf("服务器端启动中...\n");
// 使用sockaddr_in 替换 sockaddr
struct sockaddr_in server_addr;
// 家族簇
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8089);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// 1. 创建socket设备
/*
* TODO 地址家族
* PF_LOCAL Host-internal protocols, formerly called PF_UNIX,
* PF_UNIX Host-internal protocols, deprecated, use PF_LOCAL,
* PF_INET Internet version 4 protocols,
* PF_ROUTE Internal Routing protocol,
* PF_KEY Internal key-management function,
* PF_INET6 Internet version 6 protocols,
* PF_SYSTEM System domain,
* PF_NDRV Raw access to network device,
* PF_VSOCK VM Sockets protocols
*
* TODO 套接字类型
* SOCK_STREAM TCP
* SOCK_DGRAM UDP
* SOCK_RAW UDP
*/
int sfd = socket(PF_INET, SOCK_STREAM, 0);
if (sfd == -1)
{
perror("创建socket设备失败");
}
// 2. 绑定socket设备到ip、端口
/*
* TODO 通用地址结构
* struct sockaddr {
* __uint8_t sa_len; // total length
* sa_family_t sa_family; // [XSI] address family
* char sa_data[14]; // [XSI] addr value (actually larger)
* };
*
* TODO 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
* };
*/
int bindResult = bind(sfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (bindResult == -1)
{
perror("绑定socket设备失败");
}
// 3. 监听客户端消息到 链接未决队列
int listenResult = listen(sfd, 10);
if (listenResult == -1)
{
perror("监听socket设备失败");
}
printf("服务器端启动成功,开始监听客户端消息...\n");
char buf[128];
while (1)
{
// 4. 读取 链接未决队列请求 返回客户端链接未决描述符
int acceptResult = accept(sfd, NULL, NULL);
if (acceptResult == -1)
{
perror("接收客户端消息失败");
}
// 5. 读取客户端消息
int r = read(acceptResult, buf, 128);
// 6. 处理客户端消息,返回给客户端
write(acceptResult, buf, r);
write(1, buf, r);
// 7. 关闭本次客户端链接
close(acceptResult);
}
return 0;
}
// 启动执行结果
dony15$ ./server_socket
服务器端启动中...
服务器端启动成功,开始监听客户端消息...
Send Data
TCP客户端
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char *msg = "Send Data\n";
char buf[128];
printf("客户端启动中...\n");
struct sockaddr_in client_addr;
client_addr.sin_family = AF_INET;
client_addr.sin_port = htons(8089);
client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
inet_pton(AF_INET, argv[1], &client_addr.sin_addr);
int cfd = socket(PF_INET, SOCK_STREAM, 0);
if (cfd == -1)
{
perror("创建socket设备失败");
}
int connectResult = connect(cfd, (struct sockaddr *)&client_addr, sizeof(client_addr));
if (connectResult == -1)
{
perror("连接服务器失败");
}
int writeResult = write(cfd, msg, strlen(msg) + 1);
if (writeResult == -1)
{
perror("向服务器发送数据失败");
}
int r = read(cfd, buf, 128);
write(1, buf, r);
close(cfd);
printf("\n客户端运行结束\n");
return 0;
}
// 启动执行结果
dony15$ ./client_socket 127.0.0.1
客户端启动中...
创建socket设备成功
连接服务器成功
Send Data
客户端运行结束
总结
本章主要为C语言笔记-25-网络-TCP网络编程