Linux开发_网络编程基础(1)

146 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第26天,点击查看活动详情

列出上小节里Linux进程编程的提出的练习案例,介绍Linux下网络编程知识点,TCP服务器、TCP客户端创建方式,实现基本通信。

任务1:进程

(1) 进程的创建和管理

(2) 命名管道与无名管道基本运用

(3) 信号的接收和发送(闹钟的信号)

 #include <stdio.h>
 #include <signal.h>
 ​
 /*信号处理函数*/
 void sighandler(int signal_num)
 {
     alarm(1);
     printf("SIGNAL:%d\n",signal_num);
 }
 ​
 int main(int argc,char **argv)
 {
     /*绑定信号到特定的函数*/
     signal(SIGALRM,sighandler);
     alarm(1); //设置闹钟
     while(1)
     {
         
     }
     return 0;
 }

需求:通过C语言代码获取其他进程(c语言代码、Shell脚本)的返回值。

(1) system(“ls -l >123.txt”); //重定向输出

(2) popen标准管道;

 #include <stdio.h>
 FILE *popen(const char *command, const char *type);
 参数解析:
 const char *command:就是需要执行的命令,就是可执行程序。例如: “ls -l” “./a.out”
 const char *type: “w”写 “r”读
 int pclose(FILE *stream);

无名管道:

 fds[0] 表示读 
 fds[1] 表示写
 int dup2(int oldfd, int newfd); //实现文件描述符的重定向
 示例: dup2(fds[1],1); //将本程序的标准输出定义到管道的写端
 标准输入:0
 标准输出:1
 标准错误:2
 FIFO文件是否可以在创建? 不可在挂载的目录下创建。

任务2:网络编程

管道: 运用多个进程之间的通信。

socket网络编程:运用于多个设备之间通信。

Socket网络编程实际对TCP/IP协议进行编程。

TCP/IP协议:

底层协议:TCP\UDP

上层协议:HTTP、FTP、NFS……..

学习网络编程需要了解的概念:

【1】能够传输网络数据的方式: 以太网有线网卡、无线网卡WIFI

【2】了解网络协议:如何区分数据是发给谁的。

【4】IP地址:同一个局域网内,每台电脑的IP地址不一样。

IP地址:区分每台电脑。

【5】端口号:同一个电脑内,区分不同的应用程序。

192.168.1.18:8585

【6】TCP协议:点对点协议(打电话),数据丢包会自动重发,传输比较稳定。

TCP协议有3次握手的过程,建立通信的基础。

一般适用于:FTP文件传输、HTTP网页数据传输等等…….

TCP协议通信中区分服务器与客户端:

服务器必须先存在,客户端才可以连接。(网络游戏)

客户端与客户端之间可以通信?必须通过服务器—模式就是(C/S)

【7】UDP协议:广播方式协议(上课一样)。

特性就是:实时性

一般适用于:视频传输、视频监控…..QQ视频

UDP协议不区分服务器与客户端,发送数据的就是服务器,接收数据的就是客户端。

【8】数据的大小端模式。电脑上的数据一般都是小端模式,网络数据大端模式。

【9】Socket编程与文件操作原理是一样。一切皆文件!

TCP服务器创建流程

【1】调用socket函数创建网络通信套接字(用法与open类似)。

【2】调用bind绑定端口的函数(填充必须要结构体成员),创建服务器。

【3】设置监听端口的数量(设置最大能够连接的客户端数量)

【4】调用accept等待

【5】调用read或者write函数进行基本通信

TCP客户端创建流程

【1】调用socket函数创建网络通信套接字(用法与open类似)。

【2】调用Connect函数连接指定的服务器

【3】调用read或者write函数进行基本通信

练习

【1】实现服务器与客户端之间的基本通信,收发数据

客户端:

 #include <stdio.h>
 #include <sys/types.h>          /* See NOTES */
 #include <sys/socket.h>
 #include <stdlib.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <string.h>
 ​
 /*
 TCP客户端的创建步骤:
 1. 创建socket套接字
 2. 连接服务器
 3. 进行通信
 */
 int main(int argc,char **argv)
 {
      if(argc!=3)
     {
         printf("参数: ./tcp_client <IP地址> <端口号>\n");
         return 0;
     }
     /*1. 创建socket套接字*/
     int sockfd;
     sockfd=socket(AF_INET,SOCK_STREAM,0);
     if(sockfd<0)
     {
         printf("客户端:套接字创建失败.\n");
         return 0;
     }
     /*2. 连接服务器*/
     struct sockaddr_in addr;
     addr.sin_family=AF_INET; //IPV4
     addr.sin_port=htons(atoi(argv[2])); //65535  服务器的端口号
     addr.sin_addr.s_addr=inet_addr(argv[1]); //服务器IP地址
     if(connect(sockfd,(const struct sockaddr *)&addr,sizeof(struct sockaddr)))
     {
         printf("客户端:连接服务器失败.\n");
         return 0;
     }
     /*3. 进行数据通信*/
     char buff[]="TCP网络编程学习";
     int cnt;
     cnt=write(sockfd,buff,strlen(buff));
     printf("客户端发送的数据:%d,%s\n",cnt,buff);
     /*4. 关闭套接字*/
     close(sockfd);
     return 0;
 }

服务器:

 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <stdlib.h>
 ​
 /*
 TCP服务器:
 1. sockt创建套接字
 2. bind绑定端口
 3. 设置监听的数量
 4. 等待客户端连接
 */
 int socket_sfd; /*保存了服务器端的套接字*/
 int socket_cfd; /*已经连接成功的客户端套接字*/
 ​
 int main(int argc,char **argv)
 {
     if(argc!=3)
     {
         printf("./server <192.168.xx.xx 本地IP地址> <服务器端口号>\n");
         exit(-1);
     }
     
     int err; //存放返回值状态
     /*1. 创建套接字*/
     socket_sfd=socket(AF_INET,SOCK_STREAM,0);
     if(socket_sfd<0)
     {
         printf("服务器端创建失败!\n");
         exit(-1);
     }
     
     /*2. 绑定端口*/
     struct sockaddr_in ServerAddr;
     ServerAddr.sin_family=AF_INET; //IPV4协议
     ServerAddr.sin_port=htons(atoi(argv[2]));      //服务器的端口号 最大值65535
     ServerAddr.sin_addr.s_addr=inet_addr(argv[1]); //IP地址赋值
     err=bind(socket_sfd,(const struct sockaddr *)&ServerAddr,sizeof(struct sockaddr));
     if(err!=0)
     {
         printf("服务器端 端口绑定失败!\n");
         exit(-1);
     }
     
     /*3. 设置监听的数量*/
     listen(socket_sfd,10);
     
     /*4. 等待客户端连接*/
     struct sockaddr_in ClientAddr; //存放已经连接成功客户端信息
     socklen_t addrlen=sizeof(struct sockaddr);    //客户端的地址长度
     socket_cfd=accept(socket_sfd,(struct sockaddr *)&ClientAddr,&addrlen);
     if(socket_cfd<0)
     {
         printf("服务器端,连接客户端失败!\r\n");
         exit(-1);
     }
     
     /*打印一些客户端的信息*/
     printf("成功连接的客户端端口号:%d\n",ntohs(ClientAddr.sin_port));
     printf("成功连接的客户端IP地址:%s\n",inet_ntoa(ClientAddr.sin_addr));
     
     /*5. 收发数据 :服务器给客户端发送10个字节的数据*/
     err=write(socket_cfd,"123456789",10);
     printf("服务器成功发送:%d 字节\r\n",err);
     return 0;
 }

【2】实现服务器与客户端之间的文件传输。(单个文件传输)