我正在尝试通过编写套接字侦听器程序来模拟telnetfunction,并将应用程序通过套接字redirect到侦听器。
在服务器端,我在本地ip(一个定义的端口)上打开一个套接字,然后像这样开始监听
sockfd = socket(AF_INET,SOCK_STREAM,0); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); bind(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr); listen(sockfd,5); neewsockfd = accept(sockfd,(struct sockaddr*)&cli_addr,&clien);
然后,我开始像这样在一个单独的线程中读取传入的数据:
while(1) { bzero(buffer,256); n= read(newsockfd,buffer,255); if(n>0) printf("%s",buffer); }
在听音码后的主例程中,我join了这样的套接字数据发送部分。
while(1) { bzero(buffer,256); getline(&buffer,&t,stdin); n=send(newsockfd,buffer,strlen(buffer),MSG_EOR); }
而对于客户端部分,我已经连接到这样的服务器。
sockfd = socket(AF_INET,SOCK_STREAM,0); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; inet_pton(AfF_INET,hostip,&serv_addr.sin_addr.s_addr) serv_addr.sin_port = htons(portno); connect(sockfd,serv_addr,sizeof(serv_addr));
然后我欺骗stdin,stdout和stderr sockfd描述符redirect控制台,如下所示。
dup2(sockfd,STDIN_FILENO); dup2(sockfd,STDOUT_FILENO); dup2(sockfd,STDERR_FILENO); close(sockfd);
最后我在客户端有这样的东西来testing控制台redirect
while(1) { bzero(mystring,256); i = getline(&string,&t,stdin); printf("Input:%s-%d\n",mystring,i); }
在上面的代码中,我希望getline被阻塞,直到我在服务器应用程序控制台上input一些字符,但是对于我的痛苦,它反复出现值0。
任何想法为什么这种行为?
用stdio(3)
混合插座stdio(3)
是一个坏主意TM 。 stdin
和stdout
都是行缓冲的 ,请参阅setbuf(3)
,这可能是什么让你在这里。 还有一个线程安全问题 – stdio
流被锁定,但是由于您已经使用GNU扩展,您可以尝试解锁对应的对象。
根据您在意见中的意见,我认为这将是解决方案:
fork(2)
之前在父进程中创建一个pipe(2)
fork(2)
fork(2)
但在execve(2)
之前, dup2(2)
管道的读文件描述符被转换成STDIN
, exec
子进程中只读标准输入 这应该避免大部分的困惑。