Telnet模拟系统(Linux c)
第3章详细设计和实现
3.1相关技术
1)TCP编程,主要包括socket()函数、bind()函数、listen()函数、recv()函数、send()函数以及客户端的connect()函数。
2)C语言中对结构体的操作,和对字符串的比较
3)对文件的读写操作
4)popen调用shell
3.2开发工具和运行环境
本系统在ubantu 16.4 LTS环境下开发,所用的工具为vi编辑器和gedit编辑器,以及gcc编译工具。
3.3主要功能的源码
3.3.1服务器端socket的建立
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) //创建socket
printf( "socket failed" );
/* 设置端口快速重用*/
optval = 1;
if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(int)) < 0 )
printf( "setsockopt failed" );
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons( PORT );
server_addr.sin_addr.s_addr = htonl( INADDR_ANY );
if ( bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) < 0 ) //绑定ip和端口号
printf( "bind failed" );
if ( listen(sockfd, MAX_LISTEN) < 0 ) //建立监听
printf( "listen failed" );
3.3.2对客户端的发送信息进行处理
while ( 1 ) {
if ( (connfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_size)) < 0 ) //响应客户端请求
printf( "accept failed" );
printf( "Server accept a client: ip = %s\n",inet_ntoa(client_addr.sin_addr) ); //打印客户端ip
/* 创建子进程处理客户端请求 */
if ( (pid = fork()) == 0 ) {
while ( 1 ) {
/* 接受客户端信息 */
if ( (recv_bits = recv(connfd, buffer, BUF_SIZE, 0)) < 0 )
printf( "recv failed" );
/* 去除最后一个字符 */
buffer[recv_bits - 1] = '\0';
/* 用户名鉴定 */
if ( recv_type == USERNAME ) {
if ( strcmp(name, buffer) != 0 ) {
if ( send(connfd, error_user,strlen(error_user), 0) < 0 )
printf( "send failed" );
break;
}else{
if ( send(connfd, correct_user,strlen(correct_user), 0) < 0 )
printf( "send failed" );
}
printf("%s正在登录:",buffer);
recv_type = PASSWORD; //设置标志为密码鉴定模式
}
/* 密码鉴定 */
else if ( recv_type == PASSWORD ) {
if ( strcmp(passwd, buffer) != 0 ) { //验证密码
if ( send(connfd, error_password,strlen(error_password), 0) < 0 )
printf( "send failed" );
} else {
if ( send(connfd, success_login, strlen(success_login), 0) < 0 )
printf( "send failed" );
printf("用户登录成功!\n");
recv_type = COMMAND; //设置标志为命令模式
}
}
/* 命令模式 */
else if( recv_type == COMMAND ) {
command(connfd,buffer);
puts("客户端输入的命令为:");
puts(buffer);
}
}
close( sockfd );
close( connfd );
exit ( 0 );
}
else
close( connfd );
}
3.3.3 执行命令函数
int command(int connfd,char*command)
{
/*
* 作用:通过popen调用shell执行command命令
* connfd: 客户端标识
* command: 命令字符串
*/
FILE *fstream = NULL;
char buff[1024];
memset(buff, 0, sizeof(buff));
if ( strcmp(exit_command, command) == 0 ) { //退出
if ( send(connfd, exit_command,strlen(exit_command), 0) < 0 )
printf( "send failed" );
printf("客户端已断开连接!\n");
return 0;
}
if(NULL == (fstream = popen(command,"r")))
{
fprintf(stderr,"execute command failed: %s",strerror(errno));
return -1;
}
while(NULL != fgets(buff, sizeof(buff), fstream))
{
//printf("%s",buff);
if ( send(connfd, buff,strlen(buff), 0) < 0 ) //将命令执行结果发送至客户端
printf( "send failed" );
}
pclose(fstream);
return 0;
}
3.3.4客户端发送与接受信息
int send_recv( int connfd,char flag )
{
/*
* 作用:客户端与服务器端信息的处理
* connfd: 服务器端标识
* flag: 输入类比标识
*/
char input_buf[ BUF_SIZE ]; //定义字符串存放输入信息
char recv_buf[ BUF_SIZE ]; //定义字符串存放服务器端返回信息
memset(input_buf, 0, sizeof(input_buf));
memset(recv_buf, 0, sizeof(recv_buf));
fgets( input_buf, BUF_SIZE, stdin ); //获取用户输入
input_buf[strlen(input_buf) - 1] = '\0'; //去除最后一个输入的确认
/* 向服务器发送消息 */
if ( send(connfd, input_buf, BUF_SIZE, 0) < 0 )
printf( "send failed" );
/* 从服务器接受消息 */
if ( recv(connfd, recv_buf, BUF_SIZE, 0) < 0 )
printf( "recv failed" );
/* 用户名处理 */
if ( flag == 'u' ) {
if ( strcmp(recv_buf, error_user) == 0 ) { //用户名错误
puts( error_user );
return FALSE;
}
}
/* 密码处理 */
else if ( flag == 'p' ) {
if ( strcmp(recv_buf, error_password) == 0 )
{ puts( error_password ); //密码错误
return FALSE;
}
}
/* 命令处理 */
else if( flag == 'c' )
{
if ( strcmp(recv_buf, exit_command) == 0 ) { //退出
printf("连接已断开\n");
return FALSE;
}
puts(recv_buf); //命令结果输出
}
return TRUE;
}
第7章 附录
7.1服务器端
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define PORT 3333
//用户名和密码
char *name="twain";
char *passwd="";
#define MAX_LISTEN 10
#define BUF_SIZE 1024
#define USERNAME 0
#define PASSWORD 1
#define COMMAND 2
//登录过程状态标识
char *error_user = "error user name";
char *error_password = "error password";
char *correct_user = "correct user";
char *success_login = "correct password";
char *exit_command = "exit";
char *exit_tip="退出连接!";
/*
* 介绍:服务器端
* 功能:
* 1.接受客户端的登录请求并验证
* 2.接受客户端的命令在本地执行并返回执行结果
*/
int command(int connfd,char*command)
{
/*
* 作用:执行command命令
* connfd: 客户端标识
* command: 命令字符串
*/
FILE *fstream = NULL;
char buff[];
memset(buff, , sizeof(buff));
if ( strcmp(exit_command, command) == ) { //退出
if ( send(connfd, exit_command,strlen(exit_command), ) < )
printf( "send failed" );
printf("客户端已断开连接!\n");
return ;
}
if(NULL == (fstream = popen(command,"r")))
{
fprintf(stderr,"execute command failed: %s",strerror(errno));
return -;
}
while(NULL != fgets(buff, sizeof(buff), fstream))
{
//printf("%s",buff);
if ( send(connfd, buff,strlen(buff), ) < ) //将命令执行结果发送至客户端
printf( "send failed" );
}/*
if(NULL != fgets(buff, sizeof(buff), fstream))
{
//printf("%s",buff);
if ( send(connfd, buff,strlen(buff), 0) < 0 )
printf( "send failed" );
}else{
if ( send(connfd, "..",sizeof("buff"), 0) < 0 )
printf( "send failed" );
}*/
pclose(fstream);
return ;
}
int main( int argc, char *argv[] )
{
int sockfd, connfd;
int optval;
int recv_type = USERNAME; //默认为USERNAME,即用户名输入模式
int client_size;
int recv_bits;
char buffer[ BUF_SIZE ];
pid_t pid;
struct sockaddr_in client_addr, server_addr;
client_size = sizeof( struct sockaddr_in );
/* 初始化各变量为零 */
memset( buffer, , BUF_SIZE );
memset( &server_addr, , sizeof(server_addr) );
memset( &client_addr, , sizeof(server_addr) );
if ( (sockfd = socket(AF_INET, SOCK_STREAM, )) < ) //创建socket
printf( "socket failed" );
/* 设置端口快速重用*/
optval = ;
if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(int)) < )
printf( "setsockopt failed" );
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons( PORT );
server_addr.sin_addr.s_addr = htonl( INADDR_ANY );
if ( bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) < ) //绑定ip和端口号
printf( "bind failed" );
if ( listen(sockfd, MAX_LISTEN) < ) //建立监听
printf( "listen failed" );
printf("telnet服务器已开启……\n");
while ( ) {
if ( (connfd = accept(sockfd, (struct sockaddr*)&client_addr, &client_size)) < ) //响应客户端请求
printf( "accept failed" );
printf( "Server accept a client: ip = %s\n",inet_ntoa(client_addr.sin_addr) ); //打印客户端ip
/* 创建子进程处理客户端请求 */
if ( (pid = fork()) == ) {
while ( ) {
/* 接受客户端信息 */
if ( (recv_bits = recv(connfd, buffer, BUF_SIZE, )) < )
printf( "recv failed" );
/* 去除最后一个字符 */
buffer[recv_bits - ] = '\0';
/* 用户名鉴定 */
if ( recv_type == USERNAME ) {
if ( strcmp(name, buffer) != ) {
if ( send(connfd, error_user,strlen(error_user), ) < )
printf( "send failed" );
break;
}else{
if ( send(connfd, correct_user,strlen(correct_user), ) < )
printf( "send failed" );
}
printf("%s正在登录:",buffer);
recv_type = PASSWORD; //设置标志为密码鉴定模式
}
/* 密码鉴定 */
else if ( recv_type == PASSWORD ) {
if ( strcmp(passwd, buffer) != ) { //验证密码
if ( send(connfd, error_password,strlen(error_password), ) < )
printf( "send failed" );
} else {
if ( send(connfd, success_login, strlen(success_login), ) < )
printf( "send failed" );
printf("用户登录成功!\n");
recv_type = COMMAND; //设置标志为命令模式
}
}
/* 命令模式 */
else if( recv_type == COMMAND ) {
command(connfd,buffer);
puts("客户端输入的命令为:");
puts(buffer);
}
}
close( sockfd );
close( connfd );
exit ( );
}
else
close( connfd );
}
return ;
}
7.2客户端
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define TRUE 1
#define FALSE -1
#define BUF_SIZE 1024
//登录过程状态标识
char *error_user = "error user name";
char *error_password = "error password";
char *correct_user = "correct user";
char *success_login = "correct password";
char *exit_command = "exit";
char *exit_tip="退出连接!";
/*
* 介绍:客户端
* 功能:
* 1.登录服务器端
* 2.登录后在服务器端对文件进行操作
*/
int send_recv( int connfd,char flag )
{
/*
* 作用:客户端与服务器端信息的处理
* connfd: 服务器端标识
* flag: 输入类比标识
*/
char input_buf[ BUF_SIZE ]; //定义字符串存放输入信息
char recv_buf[ BUF_SIZE ]; //定义字符串存放服务器端返回信息
memset(input_buf, , sizeof(input_buf));
memset(recv_buf, , sizeof(recv_buf));
fgets( input_buf, BUF_SIZE, stdin ); //获取用户输入
input_buf[strlen(input_buf) - ] = '\0'; //去除最后一个输入的确认
/* 向服务器发送消息 */
if ( send(connfd, input_buf, BUF_SIZE, ) < )
printf( "send failed" );
/* 从服务器接受消息 */
if ( recv(connfd, recv_buf, BUF_SIZE, ) < )
printf( "recv failed" );
/* 用户名处理 */
if ( flag == 'u' ) {
if ( strcmp(recv_buf, error_user) == ) { //用户名错误
puts( error_user );
return FALSE;
}
}
/* 密码处理 */
else if ( flag == 'p' ) {
if ( strcmp(recv_buf, error_password) == )
{ puts( error_password ); //密码错误
return FALSE;
}
}
/* 命令处理 */
else if( flag == 'c' )
{
if ( strcmp(recv_buf, exit_command) == ) { //退出
printf("连接已断开\n");
return FALSE;
}
puts(recv_buf); //命令结果输出
}
return TRUE;
}
int main( int argc, char *argv[] )
{
int connfd;
int serv_port;
char recv_buf[ BUF_SIZE ];
struct sockaddr_in serv_addr;
if ( argc != ) {
printf( "输入格式为: ./c [ip] [port]\n" );
exit ( );
}
memset( &serv_addr, , sizeof(struct sockaddr_in) );//置零
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons( atoi(argv[]) );
inet_aton( argv[], &serv_addr.sin_addr );
if ( serv_addr.sin_port == ||serv_addr.sin_addr.s_addr == ) {
fprintf( stderr, "输入格式为: ./c [ip] [port]\n" );
exit ( );
}
connfd = socket( AF_INET, SOCK_STREAM, ); //创建socket
if ( connfd < )
printf( "socket failed" );
if ( connect(connfd, (struct sockaddr *)&serv_addr,sizeof(struct sockaddr)) < ) //连接服务器
{
printf( "connect failed" );
exit();
}
printf("请输入用户名:");
/*输入操作*/
if ( send_recv( connfd, 'u' ) == TRUE )
{
printf("请输入密码:");
if ( send_recv( connfd,'p' )== TRUE )
{
while()
{
printf("guest@ubantu:");
if ( send_recv( connfd, 'c' )== FALSE )
{
close( connfd );
exit();
}
}
}
}
close( connfd );
return ;
}
Telnet模拟系统(Linux c)的更多相关文章
- Windows使用Telnet连接Linux服务器初探(待实践)
在Windows下可以适用Telnet连接Linux服务器,但是前提是在Linux下需要安装Tlenet-Server.还要开启防火的23端口.搞定之后就可以用telnet IP进行连接. 但是,我发 ...
- Linux学习之七-配置Telnet连接Linux服务器
配置Telnet连接Linux服务器 通过telnet可以从windows平台访问linux 服务器 ,实现和ssh 客户端一样的效果,区别在于通过ssh连接更安全. 检查Linux系统中是否安装了t ...
- 设置用root用户telnet到linux系统
默认情况下,ROOT用户不能以telnet方式连接Linux操作系统,而且也是不安全的.但从技术上来讲,是可以实现的. #mv /etc/securetty /etc/securetty.bak 保存 ...
- 如何开启telnet服务LINUX&Windows
一.LINUX centos 1.Linux安装telnet包 # yum install telnet* # rpm -qa |grep telnet telnet-server-0.17-47.e ...
- linux中脚本权限问题以及win下使用telnet测试linux端口
一个脚本叫up,执行脚本报错如下: -bash: ./up: Permission denied 解决: chmod +rx up 在执行,OK了. /************************ ...
- linux telnet命令参数及用法详解--telnet连接远程终端命令
功能说明:远端登入. 语 法:telnet [-8acdEfFKLrx][-b<主机alias.html' target='_blank'>别名>][-e<脱离字符>][ ...
- Linux 下Telnet 服务安装
Linux 下Telnet 服务安装 注:以下所有命令均在root用户下执行. 命令测试在Linxu版本6.x下完成,部分命令不适用Linux 7.0以上 1.简介 默认情况下Linux只安装了Tel ...
- Windows 如何使用telnet管理虚拟机Linux
Linux远程登录的工具很多,如putty,SecureCRT…… 其实借助Windows的telnet工具就可以在命令提示符轻松的登录到Linux系统进行操作了. 虽然telnet很简单,但还是要进 ...
- Linux(十)___iptables防火墙
一.防火墙的作用 三.防火墙的分类 三.iptables基本语法: 表: 常用filter,nat用于地址映射转换. 配置文件: /etc/sysconfig/iptables 过滤表信息 . 查看i ...
随机推荐
- c# 线程池:开启10个线程运行Fibonacci,并在所有线程运行完后,得出结果。
namespace CAThreadPool { class ThreadpoolDemo6 { static void Main(string[] args) { ; // One event is ...
- EBS请求定义成菜单
1. 将请求定义为“功能”路径:系统管理员 –应用产品-函数输入自定义的功能名称,用户功能名以及说明 “特性”TAB页: 类型选择“表单”,其余两个字段默认:在表单TAB页: 表单字段:选择“运行 ...
- npm私有仓库搭建
背景 Node.js开发本地项目,有时不同项目之间存在依赖,如果不想把项目发布到npm社区的仓库,则需要有自己本地的仓库. 有些公司采用的是内网开发,很多npm资源无法从内网去下载. sinopia( ...
- C# 实现水印
直接上源码 public class WaterTextBox : TextBox { //private const int EM_SETCUEBANNER = 0x1501; //[DllImpo ...
- 更改SQL实例端口
为SQL Server使用非标准的端口 你正在使用标准的端口号1433来连接SQL Server 2005吗?你考虑过设置SQL Server来监听一个不同于1433的端口号吗?我曾经就是这样.在这篇 ...
- APUE 4.8 umask函数
- HTML5 JS 实现浏览器全屏(F11的效果)
项目中有需要使用JS来控制浏览器全屏的方法 DEMO地址: http://zhongxia245.github.io/demo/js2fullpanel.html function fullScree ...
- Spring 源码阅读之BeanFactory
1. BeanFactory 的结构体系如下: 2. XmlBeanFactory ,装载Spring配置信息 package org.springframework.beans.factory.xm ...
- php解决约瑟夫环的问题
php里面解决约瑟夫环还是比较方面的,但是下面的方法太费空间 <?php class SelectKing{ private $m;//幅度 private $n;//总数 public fun ...
- Java 处理cookie的方法
一.java创建cookie 方法一: Response.Cookies["userName"].Value = "patrick"; Response.Coo ...