LINUX--综合程序设计
2021/11/3 7:13:12
本文主要是介绍LINUX--综合程序设计,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 实验环境:
- 实验内容与步骤
- PART 1 程序理解 (socket实现服务器端-客户端的TCP通信)
- 服务器代码:
- 客户端代码:
- PART 2 程序实现
- 服务器代码:
- 客户端代码:
实验环境:
cnetos7
ip:192.168.43.168
实验内容与步骤
PART 1 程序理解 (socket实现服务器端-客户端的TCP通信)
服务器代码:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <signal.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define SERVER_PORT 6000 //端口号可自己设置 #define SERVER_IP "192.168.126.128" // IP 地址请自己根据实际情况设置 int listen_fd = -1; void signal_handler(int arg) { printf("close listen_fd(signal = %d)\n", arg); close(listen_fd); exit(0); } int main(int argc, const char *argv[]) { int new_fd = -1; struct sockaddr_in server; struct sockaddr_in client; socklen_t saddrlen = sizeof(server); socklen_t caddrlen = sizeof(client); signal(SIGINT, signal_handler); memset(&server, 0, sizeof(server)); memset(&client, 0, sizeof(client)); listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd < 0) { printf("socket error!\n"); return -1; } server.sin_family = AF_INET; server.sin_port = htons(SERVER_PORT); server.sin_addr.s_addr = inet_addr(SERVER_IP); if (bind(listen_fd, (struct sockaddr *)&server, saddrlen) < 0) { printf("bind error!\n"); return -1; } if (listen(listen_fd, 5) < 0) { printf("listen error!\n"); return -1; } char rbuf[256] = {0}; int read_size = 0; while (1) { new_fd = accept(listen_fd, (struct sockaddr *)&client, &caddrlen); if (new_fd < 0) { perror("accept"); return -1; } printf("new client connected.IP:%s,port:%u\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); while (1) { read_size = read(new_fd, rbuf, sizeof(rbuf)); if (read_size < 0) { printf("read error!\n"); continue; } else if (read_size == 0) { printf("client (%d) is closed!\n", new_fd); close(new_fd); break; } printf("recv:%s\n", rbuf); } } close(listen_fd); return 0; }
客户端代码:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <signal.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define SERVER_PORT 6000 // 端口 #define SERVER_IP "192.168.126.128" //服务器IP地址 int main(int argc, const char *argv[]) { int connect_fd = -1; struct sockaddr_in server; socklen_t saddrlen = sizeof(server); memset(&server, 0, sizeof(server)); connect_fd = socket(AF_INET, SOCK_STREAM, 0); if (connect_fd < 0) { printf("socket error!\n"); return -1; } server.sin_family = AF_INET; server.sin_port = htons(SERVER_PORT); server.sin_addr.s_addr = inet_addr(SERVER_IP); if (connect(connect_fd, (struct sockaddr *)&server, saddrlen) < 0) { printf("connect failed!\n"); return -1; } char buf[256] = {0}; while (1) { printf(">"); fgets(buf, sizeof(buf), stdin); if (strcmp(buf, "quit\n") == 0) { printf("client will quit!\n"); break; } write(connect_fd, buf, sizeof(buf)); } close(connect_fd); return 0; }
运行结果:
打开第3个终端窗口,运行client窗口,观察程序运行结果。分析:服务器端能同时响应两个客户端的连接请求吗?
打开第三个窗口运行client后结果:
服务器并没有接收到第二个客户端发来的信息。
但是在这个时候将第一个客户端的连接断开后服务器接收到了第二个客户端发来的信息。
PART 2 程序实现
PART 1 中实现的功能是客户端向服务器端发送信息,服务器端接收到信息后显示出来,在理解上述程序的基础上,对程序功能进行扩展,实现如下功能:
(1)服务器端接收到信息后,进行简单的加密处理,然后将加密之后的字符串发回给客户端,客户端将其显示出来。 加密策略为:如果字符为英文字符,则进行大小写转换,如果是数字字符,则将相应的数字加6再取个位数,如果是其他字符,则保留原样。如服务器接收到的字符串为:A1b2D9#6,则加密之后的字符串为:a7B8d5#2
(2)如果服务器端接收的字符串是"time",则不需要进行加密,而是将系统时间发送给客户端,客户端显示收到的信息。
服务器代码:
#include <stdio.h> #include <time.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <signal.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define SERVER_PORT 6000 //端口号可自己设置 #define SERVER_IP "192.168.43.168" // IP 地址请自己根据实际情况设置 int listen_fd = -1; //socket描述符 void signal_handler(int arg) //信号处理,遇到ctrl + c退出 { printf("close listen_fd(signal = %d)\n", arg); close(listen_fd); exit(0); } //获得系统时间 char* showTime() { time_t timer = time(NULL); char* showTime = asctime(localtime(&timer)); return showTime; } //特定的加密操作 void endecrypt(char *rbuf){ char *p = rbuf; while (*p != '\0'){ if((*p >= 'a' && *p <= 'z')) { *p = *p - 32; }else if(*p >= 'A' && *p <= 'Z'){ *p = *p + 32; }else if(*p >= '0' && *p <= '9'){ *p = (((*p - '0') + 6) % 10) + '0'; } p++; } } int main(int argc, const char *argv[]) { int new_fd = -1; //socket新描述符 struct sockaddr_in server; struct sockaddr_in client; socklen_t saddrlen = sizeof(server); socklen_t caddrlen = sizeof(client); signal(SIGINT, signal_handler); memset(&server, 0, sizeof(server)); //初始化 memset(&client, 0, sizeof(client)); listen_fd = socket(AF_INET, SOCK_STREAM, 0); //创建socket,并更新socket描述符 if (listen_fd < 0) //如果socket创建失败则退出 { printf("socket error!\n"); return -1; } server.sin_family = AF_INET; //设置协议类型为IPv4 server.sin_port = htons(SERVER_PORT); //设置端口 server.sin_addr.s_addr = inet_addr(SERVER_IP); //将服务器点分十进制ip转换为32位二进制网络字节序并设置 if (bind(listen_fd, (struct sockaddr *) &server, saddrlen) < 0) //绑定一个端口号和ip,使套接口与指定的端口号和ip相关联 { printf("bind error!\n"); return -1; } if (listen(listen_fd, 5) < 0) //设置监听,最大连接请求数为5 { printf("listen error!\n"); return -1; } char rbuf[256] = {0}; //缓冲区 int read_size = 0; while (1) { new_fd = accept(listen_fd, (struct sockaddr *) &client, &caddrlen); //接受服务请求,并设置最新socket描述符 if (new_fd < 0) { perror("accept"); return -1; } printf("new client connected.IP:%s,port:%u\n", inet_ntoa(client.sin_addr),ntohs(client.sin_port)); //打印出ip和端口提示 while (1) //对接受到的数据进行处理 { read_size = read(new_fd, rbuf, sizeof(rbuf)); //进行读操作,read_size存储数据大小 if (read_size < 0) { printf("read error!\n"); continue; } else if (read_size == 0) { printf("client (%d) is closed!\n", new_fd); close(new_fd); break; } printf("----------------receive---------------\n"); printf("%s\n", rbuf); printf("----------------over!-----------------\n"); //printf("i want to test:%d len=%d\n",strncmp(rbuf, "time\n",strlen(rbuf)),strlen(rbuf)); if (!strncmp(rbuf, "time\n",strlen(rbuf) - 1)) { //这里-1是将换行符去掉 /* * 当fgets将输入写入rbuf时,会包括换行符 */ //printf("this\n"); //char *time = showTime(); //rbuf = showTime(); //printf("the time:%s\n sizeof_time:%d",time, sizeof(time)); strcpy(rbuf,showTime()); //将系统时间复制到rbuf write(new_fd, rbuf, sizeof(rbuf)); //数据发送 }else{ // printf("endecrypt"); endecrypt(rbuf); // printf("encrypt mess:%s\n",rbuf); write(new_fd,rbuf,sizeof(rbuf)); } printf("---------------i had send it over---------------\n"); } } printf("i will cloes\n"); close(listen_fd); return 0; }
客户端代码:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <signal.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define SERVER_PORT 6000 // 端口 #define SERVER_IP "192.168.43.168" //服务器IP地址 int main(int argc, const char *argv[]) { int connect_fd = -1; struct sockaddr_in server; socklen_t saddrlen = sizeof(server); memset(&server, 0, sizeof(server)); connect_fd = socket(AF_INET, SOCK_STREAM, 0); if (connect_fd < 0) { printf("socket error!\n"); return -1; } server.sin_family = AF_INET; server.sin_port = htons(SERVER_PORT); server.sin_addr.s_addr = inet_addr(SERVER_IP); if (connect(connect_fd, (struct sockaddr *) &server, saddrlen) < 0) { printf("connect failed!\n"); return -1; } char buf[256] = {0}; while (1) { printf(">"); fgets(buf, sizeof(buf), stdin); if (strcmp(buf, "quit\n") == 0) { printf("client will quit!\n"); break; } write(connect_fd, buf, sizeof(buf)); printf("-----------------have a message from server----------------\n"); char sbuf[256] = {0}; int read_size = read(connect_fd, sbuf, sizeof(sbuf)); if (read_size < 0) { printf("read error!\n"); continue; } else if (read_size == 0) { printf("mess over!\n"); } printf("messg:%s\n", sbuf); printf("---------------------messg over!---------------------------\n"); } close(connect_fd); return 0; }
运行结果:
这篇关于LINUX--综合程序设计的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法