我试图通过编写套接字侦听器程序来模拟telnet功能,并且应用程序通过套接字将其控制台重定向到侦听器。
在服务器端,我在我的本地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);
}
在监听代码之后的主程序中,我添加了这样的套接字数据发送部分。
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描述符,以便重定向控制台,如下所示。
dup2(sockfd,STDIN_FILENO);
dup2(sockfd,STDOUT_FILENO);
dup2(sockfd,STDERR_FILENO);
close(sockfd);
最后我在客户端有类似的东西来测试控制台重定向
while(1)
{
bzero(mystring,256);
i = getline(&string,&t,stdin);
printf("Input:%s-%d\n",mystring,i);
}
在上面的代码中,我希望在我在服务器应用程序控制台上输入一些字符之前阻止getline,但是对于我的痛苦,它会反复出现值0。
知道这种行为的原因吗?
答案 0 :(得分:2)
将套接字与stdio(3)
混合是一个坏主意 TM 。 stdin
和stdout
都是行缓冲,请参阅setbuf(3)
,这可能就是您的最佳选择。还有一个线程安全问题 - stdio
流被锁定,但由于你已经使用了GNU扩展,你可以尝试他们的unlocked对应物。
根据您在评论中的输入,我认为这将是解决方案:
fork(2)
pipe(2)
dup2(2)
中,管道的读取文件描述符在STDIN
后fork(2)
之前execve(2)
exec
- ed子进程中只读了标准输入这应避免大部分混淆。