用socket通讯远程执行命令
服务器端程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
//服务器端程序: /********************************************************** * server.c * 服务器端程序 * *********************************************************/ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<netdb.h> #include<sys/socket.h> #include<netinet/in.h> #include<arpa/inet.h> #define BUFSIZE 8192 #define DEFAULT_PORT 5320 enum { CMD_NAME, SRC_PORT }; int execute(const char *command, char *buf, int bufmax); int main(int argc, char *argv[]) { struct sockaddr_in server; //服务器地址 struct sockaddr_in client; //客户机地址 socklen_t len; //sockaddr_in的长度 int port; //服务器端口号 int s; //接收报文用描述符 int s0; //接收连接用描述符 int cn; //接收命令的字数 int sn; //发送报文的字节数 int rn; //接收报文的字节数 char cmd1[BUFSIZE]; //第一个语句命令 char cmd2[BUFSIZE]; //第二个语句命令 char recv_buf[BUFSIZE]; //接收缓冲区 char send_buf[BUFSIZE]; //发送缓冲区 //实际参数的处理(端口号) if (argc == 2) { if ((port = atoi(argv[SRC_PORT])) == 0) { struct servent *se; //服务信息 if ((se = getservbyname(argv[SRC_PORT], "tcp")) != NULL) port = (int) ntohs((u_short) se->s_port); else { fprintf(stderr, "getservbyname error\n"); exit(EXIT_FAILURE); } } } else port = DEFAULT_PORT; //使用TCP协议打开一个套接字 if ((s0 = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); exit(EXIT_FAILURE); } //设定服务器地址 memset((char *) &server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(INADDR_ANY); server.sin_port = htons(port); if (bind(s0, (struct sockaddr *) &server, sizeof(server)) < 0) { perror("bind"); exit(EXIT_FAILURE); } //开始接受建立连接请求 listen(s0, 5); //接收连接循环 while (1) { //接收连接处理 len = sizeof(client); if ((s = accept(s0, (struct sockaddr *) &client, &len)) < 0) { perror("accept"); exit(EXIT_FAILURE); } printf("Connected From '%s'\n", inet_ntoa(client.sin_addr)); #ifdef FORK_SERVER if (fork() != 0) { close(s); continue; } close(s0); #endif //服务器处理的主要子程序 while (1) { int i = 0; //接收字符的计数器 sn = sprintf(send_buf, "TCP>"); send(s, send_buf, sn, 0); #if 0 receive: //流型数据的接收处理 if ((rn = recv(s, &recv_buf[i], 1, 0)) < 0) break; //以换行为单位进行接收处理 if (recv_buf[i] != '\n') { i++; if (i < BUFSIZE - 1) goto receive; } #endif #if 1 int flag = 0; do { //流型数据的接收处理 if ((rn = recv(s, &recv_buf[i], 1, 0)) < 0) { flag = 1; break; } //以换行为单位进行接收处理 if (recv_buf[i] != '\n') { i++; } else break; } while (i < BUFSIZE - 1); if (flag == 1) break; #endif recv_buf[i] = '\0'; printf("receive '%s'\n", recv_buf); //接收命令的处理 if ((cn = sscanf(recv_buf, "%s%s", cmd1, cmd2)) <= 0) continue; else if (cn == 2 && strcmp(cmd1, "show") == 0) { if (strcmp(cmd2, "route") == 0) #ifdef _linux sn = execute("/usr/bin/netstat -rn", send_buf, BUFSIZE); #else sn = execute("/bin/netstat -rn", send_buf, BUFSIZE); #endif else if (strcmp(cmd2, "arp") == 0) #ifdef _linux sn = execute("/usr/sbin/arp -an", send_buf, BUFSIZE); #else sn = execute("/sbin/arp -an", send_buf, BUFSIZE); #endif else if (strcmp(cmd2, "tcp") == 0) #ifdef _linux sn = execute("/usr/bin/netstat -tn", send_buf, BUFSIZE); #else sn = execute("/bin/netstat -tn", send_buf, BUFSIZE); #endif else if (strcmp(cmd2, "nic") == 0) sn = execute("/sbin/ifconfig -a", send_buf, BUFSIZE); else sn = sprintf(send_buf, "parameter error '%s'\n" "show[route|arp|tcp|nic]\n", cmd2); } else if (cn == 1) { if (strcmp(cmd1, "quit") == 0) break; send_buf[0] = '\0'; if (strcmp(cmd1, "help") != 0) sprintf(send_buf, "command error '%s'\n", cmd1); strcat(send_buf, "command:\n" "show route\n" "show arp\n" "show tcp\n" "show nic\n" "quit\n" "help\n"); sn = strlen(send_buf); } else sn = sprintf(send_buf, "command error '%s'\n", cmd1); if (sn == 0) sn = sprintf(send_buf, "\n"); if (send(s, send_buf, sn, 0) < 0) break; printf("%s", send_buf); } printf("Connection closed.\n"); close(s); } close(s0); return EXIT_SUCCESS; } /* *int execute(char *command,char *buf,int bufmax); * *功能 * 执行命令,将结果存储到缓冲区中 *实际参数 * char *command; 所执行的命令 * char *buf; 存储输出结果的缓冲区 * int bufmax 缓冲区的大小 *返回值 * int 存储到缓冲区的字符数 */ int execute(const char *command, char *buf, int bufmax) { FILE *fp; //文件指针 int i; //输入数据的字节数 if ((fp = popen(command, "r")) == NULL) { perror(command); i = sprintf(buf, "server error: '%s' cannot execute.\n", command); } else { i = 0; while ((buf[i] = fgetc(fp)) != EOF && i < bufmax - 1) i++; pclose(fp); } return i; } |
客户端程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
//以下是客户端程序! /*************************************************** * client.c * 在Red Hat 9.0 GCC下调试通过! * 在运行服务器端程序之后, * 再运行客户端,否则,连接会失败! * ./client 你的ip地址 [端口] * 呵呵!! * GoodLuck ***************************************************/ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<netdb.h> #include<sys/socket.h> #include<sys/time.h> #include<sys/types.h> #include<netinet/in.h> #include<arpa/inet.h> #define BUFSIZE 8192 #define DEFAULT_PORT 5320 enum { SMD_NAME, DST_IP, DST_PORT }; int main(int argc, char *argv[]) { struct sockaddr_in server; //服务器地址 unsigned long dst_ip; //服务器IP地址 int port; //端口号 int s; //套接字的描述符 int n; //输入数据的字节数 char buf[BUFSIZE]; //接收缓 char cmd[BUFSIZE]; //发送缓 struct timeval tv; //select超时时间 fd_set readfd; //使用select检索出的描述符 //实际参数的检查 if (argc != 2 && argc != 3) { fprintf(stderr, "Usage: %s hostname[port]\n", argv[0]); exit(EXIT_FAILURE); } //检索服务器的ip地址 if ((dst_ip = inet_addr(argv[DST_IP])) == INADDR_NONE) { struct hostent *he; //主机信息 if ((he = gethostbyname(argv[DST_IP])) == NULL) { fprintf(stderr, "gethostbyname error\n"); exit(EXIT_FAILURE); } memcpy((char *) &dst_ip, (char *) he->h_addr, sizeof(he->h_addr)); } //检索服务器的端口号 if (argc == 3) { if ((port = atoi(argv[DST_PORT])) == 0) { struct servent *se; //服务信息 if ((se = getservbyname(argv[DST_PORT], "tcp")) != NULL) port = (int) ntohs((u_short) se->s_port); else { fprintf(stderr, "getservbyname error\n"); exit(EXIT_FAILURE); } } } else port = DEFAULT_PORT; //使用TCP协议打开一个套接字 if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); exit(EXIT_FAILURE); } //设定服务器的地址,建立一个连接 memset((char *) &server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr = dst_ip; server.sin_port = htons(port); if (connect(s, (struct sockaddr *) &server, sizeof(server)) < 0) { perror("connect"); exit(EXIT_FAILURE); } printf("Connected to '%s'\n", inet_ntoa(server.sin_addr)); //客户机处理的主要子程序 while (1) { //select超时的设定 tv.tv_sec = 600; tv.tv_usec = 0; //标准输入,有无来自服务器的报文 FD_ZERO(&readfd); FD_SET(0, &readfd); FD_SET(s, &readfd); if ((select(s + 1, &readfd, NULL, NULL, &tv)) <= 0) { fprintf(stderr, "\nTimeout\n"); break; } //标准输入 if (FD_ISSET(0, &readfd)) { if ((n = read(0, buf, BUFSIZE - 1)) <= 0) break; buf[n] = '\n'; sscanf(buf, "%s", cmd); if (strcmp(cmd, "quit") == 0) break; if (send(s, buf, n, 0) <= 0) break; } //服务器 if (FD_ISSET(s, &readfd)) { if ((n = recv(s, buf, BUFSIZE - 1, 0)) <= 0) { fprintf(stderr, "connection closed.\n"); exit(EXIT_FAILURE); } buf[n] = '\0'; printf("%s", buf); fflush(stdout); } } strcpy(buf, "quit"); send(s, buf, n, 0); close(s); return EXIT_SUCCESS; } |
server还是linux,如果client是windows就这么弄,(一个demo~~自己视情况改改吧):server.c代码不变)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
#include <stdio.h> #include <Winsock2.h> #pragma comment( lib, "ws2_32.lib" ) #define SVR_ADDR "172.18.131.241" #define SVR_PORT 5320 void main() { WSADATA wsaData; if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0 ) { return; } SOCKET sock_id=socket(AF_INET,SOCK_STREAM,0); if ( sock_id == INVALID_SOCKET ) { printf("socket error.\n"); return; } SOCKADDR_IN addr_svr; int addrlen=sizeof(struct sockaddr_in); memset(&addr_svr, 0,addrlen); addr_svr.sin_family=AF_INET; addr_svr.sin_addr.s_addr=inet_addr(SVR_ADDR); addr_svr.sin_port=htons(SVR_PORT); if(connect(sock_id,(SOCKADDR*)&addr_svr,sizeof(SOCKADDR)) != 0){ printf("connect error.\n"); return; } char buf[100]; int bufLen = 100; fd_set readfd; int s=0; int n=0; struct timeval tv; int BUFSIZE = 64; while(true) { if((n=recv(sock_id,buf,BUFSIZE-1,0))<=0){ fprintf(stderr,"connection closed.\n"); exit(EXIT_FAILURE); } buf[n]='\0'; printf("%s",buf); fflush(stdout); strcpy(buf,"/bin/netstat -rn\n"); int len = strlen(buf); if(send(sock_id,buf,len,0)<=0) break; } closesocket(sock_id); } |
发表评论
要发表评论,您必须先登录。