尝试编写原始测试。程序必须启动tcp-server,接收连接并将接收的数据重定向到分叉程序。这是代码:
#include "TcpServer.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <termios.h>
#include <stropts.h>
#include <sys/ioctl.h>
//test
#include <pty.h>
int main() {
if (setsid() < 1) {
perror("cannot setsid()");
return 1;
}
TcpServer tcp_server;
int client;
char buf[1024];
int master, slave;
char * slave_name;
bzero(buf, sizeof(buf));
tcp_server.setPort(1025);
int server = tcp_server.startup();
client = accept(server, NULL, NULL);
fprintf(stderr, "forking...\n");
pid_t pid = forkpty(&master, NULL, NULL, NULL);
if (pid == 0) {
setsid();
fprintf(stderr, "slave pty is opened\n");
fprintf(stdout, "hello, client!\n");
char * cmd[] = {"upper.py", NULL};
fprintf(stderr, "slave: start to login\n");
int res = execvp("upper.py", cmd);
if (res < 0) {
fprintf(stderr, "trouble while running exec - '%s'\n", strerror(errno));
return 1;
}
fprintf(stderr, "slave: quit\n");
return 0;
} else if (pid < 0) {
perror("cannot fork off process");
return 1;
}
fd_set in;
int max_fd, n;
struct termios ot, t;
tcgetattr(master, &ot);
t = ot;
t.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOCTL | ECHOE | ECHOK | ECHOKE | ECHONL | ECHOPRT );
t.c_iflag |= IGNBRK;
t.c_cc[VMIN] = 1;
t.c_cc[VTIME] = 0;
tcsetattr(master, TCSANOW, &t);
while (1) {
FD_ZERO(&in);
max_fd = (master > max_fd) ? master : max_fd;
FD_SET(master, &in);
max_fd = (client > max_fd) ? client : max_fd;
FD_SET(client, &in);
fprintf(stderr, "select starts\n");
if (select(max_fd + 1, &in, NULL, NULL, NULL) < 0) {
fprintf(stderr, "select returned incorrectly\n");
if (errno == EINTR)
continue;
perror("error while select");
return 1;
}
if (FD_ISSET(client, &in)) {
fprintf(stderr, "client is set\n");
n = recv(client, buf, sizeof(buf), 0);
if (n < 0) {
fprintf(stderr, "error while receiving data from client '%s'\n", strerror(errno));
return 1;
}
if (n <= sizeof(buf)) {
buf[n] = 0;
}
fprintf(stderr, "received from client: '%s'\n", buf);
n = write(master, buf, n);
tcflush(master, TCIOFLUSH);
}
if (FD_ISSET(master, &in)) {
fprintf(stderr, "master is set ");
n = read(master, buf, sizeof(buf));
if (n < 0) {
fprintf(stderr, ": %s - ", strerror(errno));
return 1;
}
if (n <= sizeof(buf))
buf[n] = 0;
fprintf(stderr, "sending data - '%s'\n", buf);
n = send(client, buf, n, 0);
}
}
return 0;
}
程序的输出:
[milo@milo telnetd]$ sudo ./server
forking...
select starts
master is set sending data - 'slave pty is opened
hello, client!
slave: start to login
'
select starts
master is set sending data - 'input string: '
select starts
client is set
received from client: 'hello'
select starts
简而言之:服务器成功地从tcp-client接收数据,将其写入master pty,但slave-end不接收它。我见过很多例子,但看不到错误。请建议我......
UPD 我尝试int len = read(STDIN_FILENO, buf, sizeof(buf));
代替execvp
,它运行正常!我想我必须发送某种控制符号,如输入......有什么想法吗?
答案 0 :(得分:1)
雅虎!我已经解决了这个问题!在输入中没有\n
符号时,错误是(正如我前面在 UPD 中所说的那样)! otherside-program等待输入,直到结束符号出现!
答案 1 :(得分:0)
您孩子要做的第一件事就是致电setsid
。来自POSIX documentation(强调我的):
如果调用,则setsid()函数将创建一个新会话 流程不是流程组的领导者。返回调用进程 应成为本次新会议的会议负责人,应为流程 新流程组的组长,没有控制权 终端强>
所以你的孩子做的第一件事就是与其控制终端脱离关系。