提交 1a0e50bc 编写于 作者: 龙的传人科龙's avatar 龙的传人科龙

2.0 测试版 完成Telnet的基本功能,支持控制一台客户端

上级 34a4f3e7
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUF_SIZE 1024
#define SIZE 8 //每次发送文件的大小
//服务器信息
int serv_sock;
struct sockaddr_in serv_adr;
//用于select的集合
fd_set reads;
fd_set cpy_reads;
int fd_max;
void error_handling(char *message);
void Shell();
int main(int argc, char *argv)
{
serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = inet_addr("100.2.169.8");
serv_adr.sin_port = htons(9190);
if (connect(serv_sock, (struct sockaddr *)&serv_adr, sizeof(serv_adr)) == -1)
error_handling("connect() error\n");
printf("Connect Ok ServerIp %s \t%d\n", inet_ntoa(serv_adr.sin_addr), ntohs(serv_adr.sin_port));
FD_ZERO(&reads);
fd_max = serv_sock;
FD_SET(0, &reads);
FD_SET(serv_sock, &reads);
while (1)
{
cpy_reads = reads;
struct timeval time_out;
time_out.tv_sec = 1;
time_out.tv_usec = 0;
int ret = select(fd_max + 1, &cpy_reads, NULL, NULL, &time_out);
if (ret == -1)
error_handling("select() error");
else if (ret == 0)
continue;
else
Shell();
}
return 0;
}
//
void Shell()
{
char buf[BUF_SIZE];
if (FD_ISSET(0, &cpy_reads)) //从屏幕读取数据
{
memset(buf, 0, BUF_SIZE);
read(0, buf, BUF_SIZE - 1);
//write(serv_sock, buf, sizeof(buf));
write(serv_sock, buf, strlen(buf)); //这里测试用strlen();
}
if (FD_ISSET(serv_sock, &cpy_reads)) //接受数据,输出到屏幕
{
memset(buf, 0, sizeof(buf));
read(serv_sock, buf, BUF_SIZE);
//write(1, &buf[0], 1);
if (buf[0] == 'e')
{
puts(buf);
int ret = system(buf);
if (ret < 0)
printf("system() error\n");
//发送文件给Server
FILE *fp;
int totlen;
char sendBuf[BUF_SIZE];
if ((fp = fopen("cmd.txt", "rb")) == NULL)
puts("fopen() error\n");
fseek(fp, 0, SEEK_END);
totlen = ftell(fp);
//发送文件长度,方便服务器
memset(sendBuf, 0, sizeof(sendBuf));
//itoa(totlen, sendBuf, 10);
sprintf(sendBuf, "%d", totlen);
ret = send(serv_sock, sendBuf, strlen(sendBuf) + 1, 0);
//printf("cmd.txt大小%d字节\n", totlen);
int cnt = totlen / SIZE;
int len1 = SIZE;
int lenlast;
if (totlen % SIZE)
{
lenlast = totlen - cnt * SIZE;
cnt = cnt + 1;
}
rewind(fp);
// int count = 0;
for (int i = 0; i < cnt - 1; i++)
{
fread(sendBuf, SIZE, 1, fp);
send(serv_sock, sendBuf, SIZE, 0);
//write(1, buf, strlen(buf));
memset(sendBuf, 0, sizeof(sendBuf));
//++count;
}
fread(sendBuf, SIZE, 1, fp);
send(serv_sock, sendBuf, 8, 0);
//write(1, buf, strlen(buf));
//printf("发送次数%d\n", ++count);
fclose(fp);
}
else
write(1, buf, sizeof(buf));
}
}
void error_handling(char *message)
{
printf("%s", message);
exit(0);
}
......@@ -13,23 +13,31 @@ int clnt_cnt = 0;
socklen_t socklen_IPV4;
int clnt_socks[Max_clnt_cnt];
struct sockaddr_in clnt_adrs[Max_clnt_cnt];
int telnet_data[Max_clnt_cnt];
/*要连接的服务器信息*/
int serv_sock; //服务器socket
struct sockaddr_in serv_adr; //服务器地址
/*用于Select的全局变量*/
fd_set reads;
fd_set cpy_reads;
int fd_max;
/*全局缓冲区*/
char buf[BUF_SIZE];
void error_handling(char *message);
void socket_handling();
void Execute(int sock);
int main(int argc, char *argv[])
{
int serv_sock; //服务器socket
struct sockaddr_in serv_adr; //服务器地址
serv_sock = socket(AF_INET, SOCK_STREAM, 0); //IPPORT_TELNET
serv_sock = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_adr, 0, sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
//serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
//char ip[20];
//puts("Enter ServerIp:");
//scanf("%s", ip);
serv_adr.sin_addr.s_addr = inet_addr("100.2.169.8");
//serv_adr.sin_addr.s_addr = inet_addr(ip);
serv_adr.sin_port = htons(9190);
if (bind(serv_sock, (struct sockaddr *)&serv_adr, sizeof(serv_adr)) == -1)
......@@ -38,11 +46,6 @@ int main(int argc, char *argv[])
if (listen(serv_sock, Max_clnt_cnt) == -1)
error_handling("listen() error\n");
//accept(serv_sock, NULL, 0);
fd_set reads;
fd_set cpy_reads;
int fd_max;
FD_ZERO(&reads);
fd_max = serv_sock;
FD_SET(serv_sock, &reads);
......@@ -60,53 +63,109 @@ int main(int argc, char *argv[])
else if (ret == 0)
continue;
else
socket_handling();
}
close(serv_sock);
return 0;
}
void socket_handling()
{
for (int i = 0; i < fd_max + 1; i++)
{
if (FD_ISSET(i, &cpy_reads))
{
for (int i = 0; i < fd_max + 1; i++)
if (i == serv_sock)
{
struct sockaddr_in tmp_cln_adr;
int tongxunsock = accept(serv_sock, (struct sockaddr *)&tmp_cln_adr, &socklen_IPV4);
struct timeval Recvtimeout;
Recvtimeout.tv_sec = 3;
Recvtimeout.tv_usec = 0;
setsockopt(tongxunsock, SOL_SOCKET, SO_RCVTIMEO, &Recvtimeout, sizeof(Recvtimeout));
clnt_adrs[++clnt_cnt] = tmp_cln_adr;
FD_SET(tongxunsock, &reads);
if (fd_max < tongxunsock)
fd_max = tongxunsock;
printf("connected client :%d\t %s %d\n", tongxunsock, inet_ntoa(tmp_cln_adr.sin_addr), ntohs(tmp_cln_adr.sin_port));
}
else
{
if (FD_ISSET(i, &cpy_reads))
sleep(1); //睡1秒确保一次性收取所有信息
int str_len;
memset(buf, 0, BUF_SIZE);
str_len = read(i, buf, BUF_SIZE); //TODO 数据太长,要接受完再发送
if (str_len == 0)
{
if (i == serv_sock)
printf("client:%d 断开连接\n", i);
FD_CLR(i, &reads);
close(i);
}
else //对客户端的数据进行处理
{
printf("buf[0] = %c\n", buf[0]);
if (buf[0] == ':') //执行客户端命令
Execute(i);
else if (buf[0] == '$') //执行命令
{
struct sockaddr_in tmp_cln_adr;
int tongxunsock = accept(serv_sock, (struct sockaddr *)&tmp_cln_adr, &socklen_IPV4);
clnt_adrs[++clnt_cnt] = tmp_cln_adr;
FD_SET(tongxunsock, &reads);
if (fd_max < tongxunsock)
fd_max = tongxunsock;
printf("connected client :%d\t %s %d\n", tongxunsock, inet_ntoa(tmp_cln_adr.sin_addr), ntohs(tmp_cln_adr.sin_port));
}
else
{
sleep(1); //睡1秒确保一次性收取所有信息
char buf[BUF_SIZE];
int str_len;
memset(buf, 0, BUF_SIZE);
str_len = read(i, buf, BUF_SIZE); //TODO 数据太长,要接受完再发送
if (str_len == 0)
{
printf("client:%d 断开连接\n", i);
FD_CLR(i, &reads);
close(i);
}
else
for (int j = serv_sock + 1; j < fd_max + 1; j++)
{
for (int j = serv_sock + 1; j < fd_max + 1; j++)
if (j != i)
{
if (j != i)
{
write(j, buf, strlen(buf));
printf("返回数据给client:%d-->%s", j, buf);
}
write(j, buf, strlen(buf));
printf("返回数据给client:%d-->%s", j, buf);
}
}
}
}
}
}
}
close(serv_sock);
}
return 0;
void Execute(int sock)
{
char prefix[] = "echo 8002904 | sudo -S";
char backfix[] = "> cmd.txt 2>&1";
char cmd_buf[BUF_SIZE + 40];
char tmp[BUF_SIZE];
memset(tmp, 0, sizeof(tmp));
strncpy(tmp, buf + 1, sizeof(buf));
//tmp[str_len - 2] = '\0';
tmp[strlen(tmp) - 1] = '\0';
sprintf(cmd_buf, "%s %s %s", prefix, tmp, backfix);
puts(cmd_buf);
write(sock + 1, cmd_buf, strlen(cmd_buf));
//printf("return cmd result\n");
//接受
FILE *fp;
fp = fopen("Temp.txt", "wb");
if (fp == NULL)
error_handling("fopen() error\n");
char recvBuf[8];
int ret = recv(sock + 1, recvBuf, 8, 0);
int Total = atoi(recvBuf); //先接收,文件大小
int cnt = 0;
while (1)
{
memset(recvBuf, 0, sizeof(recvBuf));
ret = recv(sock + 1, recvBuf, 8, 0);
fwrite(recvBuf, ret, 1, fp);
write(sock, recvBuf, ret); //接完就发
//fflush(NULL);
cnt += ret;
if (cnt >= Total || ret == -1)
break;
}
fclose(fp);
}
void error_handling(char *message)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册