getline()函数表现奇怪

时间:2011-08-03 07:32:55

标签: c linux sockets

我试图通过编写套接字侦听器程序来模拟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。

知道这种行为的原因吗?

1 个答案:

答案 0 :(得分:2)

将套接字与stdio(3)混合是一个坏主意 TM stdinstdout都是行缓冲,请参阅setbuf(3),这可能就是您的最佳选择。还有一个线程安全问题 - stdio流被锁定,但由于你已经使用了GNU扩展,你可以尝试他们的unlocked对应物。

编辑0:

根据您在评论中的输入,我认为这将是解决方案:

  • 在执行fork(2)
  • 之前在父进程中创建pipe(2)
  • 在chaild进程dup2(2)中,管道的读取文件描述符在STDINfork(2)之前execve(2)
  • 之前
  • 在新exec - ed子进程中只读了标准输入
  • 在父进程 copy 中将标准输入写入管道的写文件描述符。

这应避免大部分混淆。