#c #linux #sockets
Вопрос:
Я использую фрагмент кода C для переадресации портов. Требование состоит в том, чтобы сделать рукопожатие между двумя портами. Это должно быть двустороннее общение. Это означает пересылку всего, что когда-либо происходит на исходном порту, в порт назначения. А затем перенаправить ответ порта назначения на порт источника.
Этот фрагмент кода работает, как и ожидалось, в моей системе mac. Но когда я запускаю этот код в системе Linux, я сталкиваюсь с одной проблемой.
Вопрос:
Код C , который я использую, состоит из 3 частей:
establish_connection_to_source();
open_connection_to_destination();
processconnetion();
В Linux: establish_connection_to_source(); и open_connection_to_destination(); работает отлично. Но processconnetion(); имеет одну проблему.
Ниже приведен способ подключения к процессу:
void processconnetion()
{
buffer *todest = new buffer(socket_list[e_source].fd,socket_list[e_dest].fd);
buffer *tosrc = new buffer(socket_list[e_dest].fd,socket_list[e_source].fd);
if (todest == NULL || tosrc == NULL){
fprintf(stderr,"out of mememoryn");
exit(-1);
}
unsigned int loopcnt;
profilecommuncation srcprofile(COMM_BUFSIZE);
profilecommuncation destprofile(COMM_BUFSIZE);
while (true) {
int withevent = poll(socket_list, 2, -1);
loopcnt ;
fprintf(stderr,"loopcnt %d socketswith events = %d source:0x%x dest:0x%xn", loopcnt, withevent, socket_list[e_source].revents, socket_list[e_dest].revents);
if ((socket_list[e_source].revents | socket_list[e_dest].revents) amp; (POLLHUP | POLLERR)) {
// one of the connections has a problem or has Hungup
fprintf(stderr,"socket_list[e_source].revents= 0x%Xn", socket_list[e_source].revents);
fprintf(stderr,"socket_list[e_dest].revents= 0x%Xn", socket_list[e_dest].revents);
fprintf(stderr,"POLLHUP= 0x%Xn", POLLHUP);
fprintf(stderr,"POLLERR= 0x%Xn", POLLERR);
int resu<
socklen_t result_len = sizeof(result);
getsockopt(socket_list[e_dest].fd, SOL_SOCKET, SO_ERROR, amp;result, amp;result_len);
fprintf(stderr, "result = %dn", result);
fprintf(stderr,"exiting as one connection had an issuen");
break;
}
if (socket_list[e_source].revents amp; POLLIN) {
srcprofile.increment_size(todest->copydata());
}
if (socket_list[e_dest].revents amp; POLLIN) {
destprofile.increment_size(tosrc->copydata());
}
}
delete todest;
delete tosrc;
close(socket_list[e_source].fd);
close(socket_list[e_dest].fd);
srcprofile.dumpseensizes("source");
destprofile.dumpseensizes("destination");
}
Вот он выдает ошибку — exiting as one connection had an issue
это значит, что if ((socket_list[e_source].revents | socket_list[e_dest].revents) amp; (POLLHUP | POLLERR))
возвращается true
. Проблема связана с портом назначения, а не с источником.
Примечание: Переменные, используемые в processconnetion();
методе: socket_list
является структурой типа pollfd
. Ниже приводится описание:
struct pollfd {
int fd;
short events;
short revents;
};
pollfd socket_list[3];
#define e_source 0
#define e_dest 1
#define e_listen 2
Ниже приведен вывод на момент выхода:
connecting to destination: destination IP / 32001.
connected...
loopcnt 1 socketswith events = 1 source:0x0 dest:0x10
socket_list[e_source].revents= 0x0
socket_list[e_dest].revents= 0x10
POLLHUP= 0x10
POLLERR= 0x8
result = 0
exiting as one connection had an issue
int withevent = poll(socket_list, 2, -1);
здесь возвращаемое значение withevent равно 1
Инициализация списка сокетов:
guard( (socket_list[e_listen].fd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP )), "Failed to create socket listen, error: %sn", "created listen socket");
void guard(int n, char *msg, char *success)
{
if (n < 0) {
fprintf(stderr, msg, strerror(errno) );
exit(-1);
}
fprintf(stderr,"n = %d %sn",n, success);
}
Я не могу разобраться в этой проблеме, так как она отлично работает в mac. Любые зацепки, объясняющие, почему такое поведение в Linux высоко ценится. Заранее спасибо.
Комментарии:
1. Я бы начал с определения того, в каком из соединений возникла проблема и в чем она заключалась.
2. @molbdnilo это с пунктом назначения
3. может быть, это не связано, но
loopcnt
не инициализировано.4. И в чем была проблема? Код ошибки? Вы не можете всерьез рассчитывать на помощь, когда опускаете всю полезную информацию.
5. Итак, один из
(socket_list[e_source]
илиsocket_list[e_dest]
получил ошибку, и вы выбрали только SO_ERROR для одного из них, и он был равен нулю. Так что ты должен принести его для другого, верно? И распечатайте это какSO_ERROR
«нетresult
«, чтобы все знали , о чем вы говорите, включая вас самих. Все это довольно просто.