写点什么

Linux 下 TCP 网络编程 - 创建服务器与客户端

作者:DS小龙哥
  • 2022 年 3 月 30 日
  • 本文字数:2596 字

    阅读完需:约 9 分钟

一、前言

互联网概念诞生于 20 世纪 60 年代末,从 9 几年中国接入互联网开始到现在,生活的每个角落都能看到网络的使用。现在物联网时代、共享经济的到来,生活中不仅仅电脑、手机可以接入网络,身边的各个设备也能接入互联网了。 比如:市政路灯、污水井盖、家用电器,汽车等等。


这篇文章介绍在 Linux 下的 socket 编程,完成 TCP 服务器、客户端的创建,实现数据通信。

二、TCP 协议介绍

在 Linux 应用层做编程,接触到是传输层协议,TCP/UDP,如果搞 Linux 网络驱动开发(网卡驱动),那么底层的网络协议就会接触的更多,协议只是一个数据格式的约定而已,自己也可以设计自己的协议。


下面这张图介绍两个设备通过网络通信的一个大致流程:



TCP 协议是点对点传输协议。TCP 协议属于 C/S 模型。TCP 协议里包含服务器和客户端。服务器必须要比客户端先存在,客户端必须连接服务器,服务器必须被客户端连接。接下来学习主要学习 TCP 服务器创建和 TCP 客户端创建,完成客户端与服务器之间的通信。TCP 服务器可以被多个客户端连接。



Linux 下 socket 编程需要用到的相关函数:


#include <sys/types.h>          /* See NOTES */#include <sys/socket.h>
int socket(int domain, int type, int protocol);AF_UNIX, AF_LOCAL Local communication unix(7)AF_INET IPv4 Internet protocols ip(7)AF_INET6 IPv6 Internet protocols ipv6(7)AF_IPX IPX - Novell protocolsAF_NETLINK Kernel user interface device netlink(7)AF_X25 ITU-T X.25 / ISO-8208 protocol x25(7)AF_AX25 Amateur radio AX.25 protocolAF_ATMPVC Access to raw ATM PVCsAF_APPLETALK AppleTalk ddp(7)AF_PACKET Low level packet interface packet(7)AF_ALG Interface to kernel crypto API
#include <sys/types.h> /* See NOTES */#include <sys/socket.h>int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);struct sockaddr { sa_family_t sa_family; char sa_data[14];}
#include <sys/types.h> /* See NOTES */#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
#define _GNU_SOURCE /* See feature_test_macros(7) */#include <sys/socket.h>int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
#include <sys/types.h> /* See NOTES */#include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
复制代码

三、案例代码

3.1 创建 TCP 服务器

#include <stdio.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <dirent.h>#include <stdlib.h>#include <pthread.h>#include <semaphore.h>#include <signal.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>
/*TCP服务器创建步骤:1. 创建socket套接字(类似于open打开文件一样)2. 绑定端口号和IP地址3. 设置监听等待队列的数量4. 等待客户端连接5. 完成正常数据收发
0x1234192.168.1.123255.255.255.255*/int main(int argc,char **argv){ if(argc!=2) { printf("./app <端口号>\n"); return 0; } int sockfd; /*1. 创建socket套接字*/ sockfd=socket(AF_INET,SOCK_STREAM,0); /*2. 绑定端口号与IP地址*/ struct sockaddr_in addr; addr.sin_family=AF_INET; addr.sin_port=htons(atoi(argv[1])); // 端口号0~65535 addr.sin_addr.s_addr=INADDR_ANY; //inet_addr("0.0.0.0"); //IP地址 if(bind(sockfd,(const struct sockaddr *)&addr,sizeof(struct sockaddr))!=0) { printf("服务器:端口号绑定失败.\n"); } /*3. 设置监听的数量*/ listen(sockfd,20); /*4. 等待客户端连接*/ int client_fd; struct sockaddr_in client_addr; socklen_t addrlen=sizeof(struct sockaddr_in); client_fd=accept(sockfd, (struct sockaddr *)&client_addr,&addrlen); if(client_fd<0) { printf("客户端连接失败.\n"); return 0; } printf("连接的客户端IP地址:%s\n",inet_ntoa(client_addr.sin_addr)); printf("连接的客户端端口号:%d\n",ntohs(client_addr.sin_port)); /*5. 完成通信*/ write(client_fd,"1234567890",10); /*6. 关闭连接*/ close(client_fd); close(sockfd); return 0;}
复制代码

3.2 创建 TCP 客户端

#include <stdio.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <dirent.h>#include <stdlib.h>#include <pthread.h>#include <semaphore.h>#include <signal.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>
/*TCP客户端创建步骤:1. 创建socket套接字(类似于open打开文件一样)2. 连接服务器 3. 完成正常数据收发
*/int main(int argc,char **argv){ if(argc!=3) { printf("./app <IP地址> <端口号>\n"); return 0; } int sockfd; /*1. 创建socket套接字*/ sockfd=socket(AF_INET,SOCK_STREAM,0); /*2. 连接服务器*/ struct sockaddr_in addr; addr.sin_family=AF_INET; addr.sin_port=htons(atoi(argv[2])); // 端口号0~65535 addr.sin_addr.s_addr=inet_addr(argv[1]); //IP地址 if(connect(sockfd,(const struct sockaddr *)&addr,sizeof(struct sockaddr_in))!=0) { printf("客户端:服务器连接失败.\n"); return 0; } /*3. 完成数据通信*/ char buff[1024]; int cnt; cnt=read(sockfd,buff,1024); buff[cnt]='\0'; printf("客户端收到的数据:%s,%d\n",buff,cnt); close(sockfd); return 0;}
复制代码


发布于: 3 小时前阅读数: 2
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022.01.06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
Linux下TCP网络编程-创建服务器与客户端_3月月更_DS小龙哥_InfoQ写作平台