学习了一下socket编程的基本知识。主要看了下《UNIX网络编程卷1:套接字联网API(第3版)》里面对socket、bind、listen、accept、connect等函数的介绍。然后参考了http://chinaunix.net/uid-28541347-id-4700074.html
原文确实挺不错,对我启发很大,这里直接贴个简单的代码,是通过客户端连接服务器,在服务器中通过fork了一个进程执行了一个简单的test.c的程序,该程序可以将输入的字符串输出,如图所示
在服务器代码中将输出重定向到了连接的connfd中(一个socket fd),并且也对输入进行了重定向,这样就可以将客户端的输入作为test.c的输入,并把返回的结果重定向给客户端输出,具体见代码
客户端代码
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PORT 9999
#define Buflen 4096
int main(int argc,char *argv[])
{
struct sockaddr_in server_addr;
int n,err;
int sockfd;
char recvline[Buflen];
//char* cmd="a\n";
char* cmd=(char*) malloc(Buflen);
setbuf(stdout,NULL);
/********************socket()*********************/
sockfd= socket(AF_INET,SOCK_STREAM,0);
/*******************connect()*********************/
//设置服务器地址结构,准备连接到服务器
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
// server_addr.sin_addr.s_addr = inet_addr(argv[1]);
err = connect(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
if(err == 0)
{
printf("client : connect to server\n");
}
else
{
printf("client : connect error\n");
return -1;
}
//与服务器端进行通信
/* memset(recvline,0,sizeof(recvline));
if( (n=read(sockfd,recvline,Buflen))>0 )
{
recvline[n]=0;
printf("%s",recvline);
}*/
while(1){
memset(cmd,0,Buflen);
if((n=read(0,cmd,Buflen))>0)
write(sockfd,cmd,strlen(cmd)); //这里相当于在pyth.py的标准输入上输入数据
if( (n=read(sockfd,recvline,Buflen))>0 )
{
recvline[n]='\0';
printf("%s",recvline);
}
}
close(sockfd);
exit(0);
}
服务端代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PORT 9999 //定义通信端口
#define BACKLOG 5 //定义侦听队列长度
#define buflen 1024
int listenfd,connfd;
int main(int argc,char *argv[])
{
struct sockaddr_in server_addr; //存储服务器端socket地址结构
struct sockaddr_in client_addr; //存储客户端 socket地址结构
int err; //返回值
pid_t pid;
/*****************socket()***************/
listenfd = socket(AF_INET,SOCK_STREAM,0);
/******************bind()****************/
//初始化地址结构
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET; //协议族
server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //本地地址
server_addr.sin_port = htons(PORT);
err = bind(listenfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
if(err<0)
{
printf("server : bind error\n");
return -1;
}
/*****************listen()***************/
err = listen(listenfd,BACKLOG); //设置监听的队列大小
if(err < 0)
{
printf("server : listen error\n");
return -1;
}
for(;;)
{
socklen_t addrlen = sizeof(client_addr);
//accept返回客户端套接字描述符
connfd = accept(listenfd,(struct sockaddr *)&client_addr,&addrlen);
if((pid = fork()) == 0) //子进程,与客户端通信
{
close(listenfd);
/* setbuf(stdout,NULL); //将标准输入、输出、错误都设置成无缓冲
setbuf(stdin,NULL);
setbuf(stderr,NULL);*/
dup2(connfd,STDOUT_FILENO); //将标准输入、输出、错误重定向到connfd
dup2(connfd,STDERR_FILENO);
dup2(connfd,STDIN_FILENO);
//if ( (err=execl("./test.py",(char*)0))<0 ) //执行pyth.py
if(execl("/home/zbr/tmp/test","test",(char*)NULL))
{
perror("execl error");
exit(1);
}
}
else
{
close(connfd);
}
}
}
结果: