popen()
可以执行shell命令,并读取此命令的返回值;
popen()函数通过创建一个 管道,调用fork()产生一个子进程,执行一个shell以运行命令来开启一个进程。可以通过这个管道执行标准输入输出操作。
这个管道必须由pclose()
函数关闭,pclose()函数关闭标准I/O流,等待命令执行结束,然后返回shell的终止状态。如果shell不能被执行,则pclose()返回的终止状态与shell已执行exit一样。
int execute(char* cmd,int sockfd,struct sockaddr_in client)
{
char buf[BUFSIZE];
FILE* fp;
char* errbuf="command cannot execute\n";
int ret;
int counter;
fp=NULL;
counter=0;
memset(buf,0,BUFSIZE);
if ((fp = popen(cmd, "r")) == NULL)
{
perror("open failed!");
ret=sendto(sockfd,errbuf,strlen(errbuf),0,(struct sockaddr*)&client,sizeof(struct sockaddr));
return -1;
}
while((!feof(fp))&&(counter<2048))
{
buf[counter]=fgetc(fp);
counter++;
}
ret=sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&client,sizeof(struct sockaddr));
if(0>ret)
return -1;
return 0;
}
#include
#include
#include
#include
#include
#include
#define PORT 8900
#define BUFSIZE 2048
/**
* @description: 将客户端内容作为命令执行,并发送给客户端
* @param:cmd:待处理的命令
* :sockfd: 通讯的套接字
* :client:对应客户端地址
* @return {*}:0 正确,-1 失败
*/
int execute(char* cmd,int sockfd,struct sockaddr_in client)
{
char buf[BUFSIZE];
FILE* fp;
char* errbuf="command cannot execute\n";
int ret;
int counter;
fp=NULL;
counter=0;
memset(buf,0,BUFSIZE);
if ((fp = popen(cmd, "r")) == NULL)
{
perror("open failed!");
ret=sendto(sockfd,errbuf,strlen(errbuf),0,(struct sockaddr*)&client,sizeof(struct sockaddr));
return -1;
}
while((!feof(fp))&&(counter<2048))
{
buf[counter]=fgetc(fp);
counter++;
}
ret=sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&client,sizeof(struct sockaddr));
if(0>ret)
return -1;
return 0;
}
int main(int argc,char** argv)
{
// declare variable
int sockfd;
struct sockaddr_in serv, client;
int opt;
int ret;
int len;
char send_buf[BUFSIZE],recv_buf[BUFSIZE];
// variable initialization
sockfd=-1;
opt=SO_REUSEADDR;
ret=-1;
len=-1;
bzero(&serv,sizeof(struct sockaddr));
bzero(&client,sizeof(struct sockaddr));
bzero(send_buf,BUFSIZE);
bzero(recv_buf,BUFSIZE);
// create socket
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(0>sockfd)
{
perror("error in creating socket]n");
exit(-1);
}
// set the socket
// allow re-bind
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(int));
//set the value for serv
serv.sin_family=AF_INET;
serv.sin_addr.s_addr=INADDR_ANY;
serv.sin_port=htons(PORT);
// bind the socket serv
ret=bind(sockfd,(struct sockaddr*)&serv,sizeof(struct sockaddr));
if(0>ret)
{
perror("error in binding\n");
exit(-1);
}
// begin communication
len=sizeof(struct sockaddr);
while(1)
{
memset(recv_buf,0,BUFSIZE);
ret=recvfrom(sockfd,recv_buf,BUFSIZE,0,(struct sockaddr*)&client,&len);
if(0>ret)
{
perror("error in recving data\n");
continue;
}
recv_buf[ret-1]='\0';
if (0==strcmp(recv_buf,"quit"))
{
fprintf(stderr,"server is terminate by client\n");
break;
}
execute(recv_buf,sockfd,client);
}
fprintf(stderr,"server is down\n");
close(sockfd);
}
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFSIZE 2048
int usage(char *cmd)
{
fprintf(stderr,"usage for %s\n:",cmd);
fprintf(stderr,"%s ipaddr port\n",cmd);
}
int main(int argc,char** argv)
{
int sockfd;
struct sockaddr_in serv;
char send_buf[BUFSIZE];
char recv_buf[BUFSIZE];
int len,ret;
if (3!=argc)
{
usage(argv[0]);
exit(-1);
}
// 初始化
sockfd=-1;
memset(&serv,0,sizeof(struct sockaddr));
memset(send_buf,0,BUFSIZE);
memset(recv_buf,0,BUFSIZE);
// 建立套接字
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if (0>sockfd)
{
perror("create socket error\n");
exit(-1);
}
// 设置服务器
serv.sin_family=AF_INET;
serv.sin_port=htons(atoi(argv[2]));
serv.sin_addr.s_addr=inet_addr(argv[1]);
while(1)
{
fprintf(stderr,"rms>>>");
fgets(send_buf,BUFSIZE,stdin);
ret=sendto(sockfd,send_buf,BUFSIZE,0,(struct sockaddr*)&serv,sizeof(struct sockaddr));
if (0>ret)
{
perror("error in sending data\n");
exit(-1);
}
send_buf[strlen(send_buf)-1]='\0';
if(0==strcmp(send_buf,"quit"))
{
fprintf(stderr,"remote control terminate\n");
break;
}
ret=recvfrom(sockfd,recv_buf,BUFSIZE,0,NULL,NULL);
if (0>ret)
{
perror("error in recving data\n");
exit(-1);
}
recv_buf[ret-1]='\0';
fprintf(stderr,"%s\n",recv_buf);
}
// 通讯结束,关闭套接字
close(sockfd);
}
/*tcpserver.c*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PORT 8900
int execute(char* command,char* buf);
int main(int argc,char** argv)
{
struct sockaddr_in server;
struct sockaddr_in client;
int len;
int port;
int listend;
int connectd;
int sendnum;
int opt;
int recvnum;
char send_buf[2048];
char recv_buf[2048];
char cmd[2048];
port= PORT;
opt = SO_REUSEADDR;
//1. create socket
if (-1==(listend=socket(AF_INET,SOCK_STREAM,0)))
{
perror("create listen socket error\n");
exit(1);
}
setsockopt(listend,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
memset(&server,0,sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(port);
//2. bind
if (-1==bind(listend,(struct sockaddr *)&server,sizeof(struct sockaddr)))
{
perror("bind error\n");
exit(1);
}
//3. listen
if (-1==listen(listend,5))
{
perror("listen error\n");
exit(1);
}
while (1)
{
// 4. accept
connectd=accept(listend,(struct sockaddr*)&client,&len);//等待客户端连接
if (-1==connectd)
{
perror("create connect socket error\n");
continue;
}
printf("connect with %s:%d\n",inet_ntoa(client.sin_addr),htons(client.sin_port));
while(1){
memset(send_buf,0,2048);
memset(recv_buf,0,2048);
//5. recv from and send to client
recvnum = recv(connectd,recv_buf,sizeof(recv_buf),0);
if (0>recvnum)
{
perror("recv error\n");
close(connectd);
break;
}
if (0==recvnum)
{
perror("the client quit abnormally\n");
close(connectd);
break;
}
recv_buf[recvnum]='\0';
printf("rms>>>%s\n",recv_buf);
if (0==strcmp(recv_buf,"quit"))
{
perror("the client quit\n");
close(connectd);
break;
}
//execute cmd
strcpy(cmd,"/bin/");
strcat(cmd,recv_buf);
execute(cmd,send_buf);
if ('\0'==*send_buf)
{
memset(cmd,0,sizeof(cmd));
strcpy(cmd,"/sbin/");
strcat(cmd,recv_buf);
execute(cmd,send_buf);
if ('\0'==*send_buf)
{
memset(cmd,0,sizeof(cmd));
strcpy(cmd,"/usr/bin/");
strcat(cmd,recv_buf);
execute(cmd,send_buf);
}
if ('\0'==*send_buf)
{
memset(cmd,0,sizeof(cmd));
strcpy(cmd,"/usr/sbin/");
strcat(cmd,recv_buf);
execute(cmd,send_buf);
}
}
if ('\0'==*send_buf)
{
sprintf(send_buf,"command is not vaild,check it please\n");
}
printf("%s\n",send_buf);
if ( 0 >send(connectd,send_buf,sizeof(send_buf),0))
{
perror("send error\n");
close(connectd);
break;
}
}
printf("disconnect with %s:%d\n",inet_ntoa(client.sin_addr),htons(client.sin_port));
}
close(listend);
return 0;
}
//execute cmd
int execute(char* command,char* buf)
{
FILE * fp;
int count;
if (NULL==(fp = popen(command,"r")))
{
perror("creating pipe error\n");
exit(1);
}
count = 0 ;
while(((buf[count] = fgetc(fp))!=EOF)&&count<2047)
count++;
buf[count]='\0';
pclose(fp);
return count;
}
server可同时连接2个clinet进行通信
#include
#include
#include
#include
#include
#include
#include
#include
#include //线程库
#define PORT 8900
int execute(char* cmd,int connectd)
{
char buf[2048];
FILE* fp;
char* errbuf="command cannot execute\n";
int ret;
int counter;
fp=NULL;
counter=0;
memset(buf,0,2048);
if ((fp = popen(cmd, "r")) == NULL)
{
perror("open failed!");
ret=send(connectd,errbuf,strlen(errbuf),0);
// ret=sendto(sockfd,errbuf,strlen(errbuf),0,(struct sockaddr*)&client,sizeof(struct sockaddr));
return -1;
}
while((!feof(fp))&&(counter<2048))
{
buf[counter]=fgetc(fp);
counter++;
}
ret=send(connectd,buf,strlen(buf),0);
if(0>ret)
return -1;
return 0;
}
// 子线程,完成服务端与某一个客户端的持续通信
//child thread
//enable server to complete constant communication with another client
void* workThread(void *arg){
int connectd = *(int*)arg;
int recvnum;
char recv_buf[2048];
while(1)
{
memset(recv_buf,'\0',2048);
if (0>(recvnum = recv(connectd,recv_buf,sizeof(recv_buf),0)))
{
perror("recv error\n");
break;
}
printf("recv cmd is %s\n", recv_buf);
// 消息中传输了回车符,会影响strcmp结果
recv_buf[recvnum] = '\0';
if (0==strcmp(recv_buf,"quit"))
{
printf("server is terminated by client\n");
close(connectd);
break;
}
else
{
execute(recv_buf,connectd);
}
}
pthread_exit(NULL);
}
int main(int argc,char** argv)
{
struct sockaddr_in server;
struct sockaddr_in client;
int len;
int port;
int listend;
int connectd;
int sendnum;
int opt;
int recvnum;
char send_buf[2048];
char recv_buf[2048];
port= PORT;
memset(send_buf,0,2048);
memset(recv_buf,0,2048);
opt = SO_REUSEADDR;
// 1.create socket
if (-1==(listend=socket(AF_INET,SOCK_STREAM,0)))
{
perror("create listen socket error\n");
exit(1);
}
setsockopt(listend,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
#ifdef DEBUG
printf("the listen id is %d\n",listend);
#endif
memset(&server,0,sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(port);
//bind addr and port
// 套接字,服务端信息绑定,接收信息的地址。两个监听套接字和连接套接字是为了并发操作。
// 2.bind
if (-1==bind(listend,(struct sockaddr *)&server,sizeof(struct sockaddr)))
{
perror("bind error\n");
exit(1);
}
//listen
// 5 是并发个数
// 3.listen
if (-1==listen(listend,5))
{
perror("listen error\n");
exit(1);
}
// main主线程,负责监听连接请求和新建消息传输线程
while (1)
{
//accept
// 连接套接字,后两个参数,客户端ip地址和长度。是通过三次握手从客户端接收。长度参数一定要初始化
// 4. accept
if (-1==(connectd=accept(listend,(struct sockaddr*)&client,&len)))
{
perror("create connect socket error\n");
continue;
}
// 创建一个新线程专门处理与某一个客户端的通信
pthread_t tid;
if(0 != pthread_create(&tid, NULL, workThread, &connectd))
{
printf("create thread fail\n");
continue;
}
printf("new client!\n");
}
fprintf(stderr,"server is down\n");
close(listend);
return 0;
}
#include
#include
#include
#include
#include
#include
#include
#include
void print_usage(char * cmd)
{
fprintf(stderr," %s usage:\n",cmd);
fprintf(stderr,"%s IP_Addr [port]\n",cmd);
}
int main(int argc,char** argv)
{
struct sockaddr_in server;
int ret;
int len;
int port;
int sockfd;
int sendnum;
int recvnum;
char send_buf[2048];
char recv_buf[2048];
if ((2>argc)|| (argc >3))
{
print_usage(argv[0]);
exit(1);
}
if (3==argc)
{
port = atoi(argv[2]);
}
//create socket
sockfd=socket(AF_INET,SOCK_STREAM,0);
if (-1==sockfd)
{
perror("create socket error\n");
exit(1);
}
memset(&server,0,sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(argv[1]);
server.sin_port = htons(port);
//connect
ret=connect(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr));
if (0 > ret)
{
perror("connect error");
close(sockfd);
exit(1);
}
//send to and recv from
while(1){
memset(send_buf,0,2048);
memset(recv_buf,0,2048);
printf("rms>>>");
scanf("%s",send_buf);
len=send(sockfd,send_buf,strlen(send_buf),0);
if (0 > len)
{
perror("send data error\n");
close(sockfd);
exit(1);
}
if (0==strcmp(send_buf,"quit"))
{
perror("remote control terminate\n");
break;
}
if (0>(len=recv(sockfd,recv_buf,2048,0)))
{
perror("recv data error\n");
close(sockfd);
exit(1);
}
recv_buf[len]='\0';
printf("%s\n",recv_buf);
}
close(sockfd);
return 0;
}