TCP-сокеты через WLAN - PullRequest
       39

TCP-сокеты через WLAN

1 голос
/ 11 августа 2011

У меня есть проект, который использует TCP-сокеты для связи между сервером и одним клиентом. На данный момент я делаю это на одном компьютере, поэтому я просто использовал локальный адрес «127.0.0.1» для адреса, чтобы связать и подключиться с обеих сторон, и он работал нормально. Теперь у меня есть второй компьютер для работы в качестве клиента, но я не знаю, как изменить адреса соответственно. Они подключены через сеть, которая не подключена к Интернету. До того как код выглядел так -

Сервер -

 struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results

//store the connecting address and size
struct sockaddr_storage their_addr;
socklen_t their_addr_size;


memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET; //local address
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address

//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    return false;
}

//make socket
fd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (fd < 0) {
    printf("\nserver socket failure %m", errno);
    return false;
}

//allow reuse of port
int yes=1;
if (setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char*) &yes,sizeof(int)) == -1) {
    perror("setsockopt");
    return false;
}

//unlink and bind
unlink("127.0.0.1");
if(bind (fd, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
    printf("\nBind error %m", errno);
    return false;
}

Клиент -

struct addrinfo hints;
struct addrinfo *servinfo; //will point to the results

memset(&hints, 0, sizeof hints); //make sure the struct is empty
hints.ai_family = AF_INET; //local address
hints.ai_socktype = SOCK_STREAM; //tcp
hints.ai_flags = AI_PASSIVE; //use local-host address

//get server info, put into servinfo
if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    return false;
}

//make socket
fd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
if (fd < 0) {
    printf("\nserver socket failure %m", errno);
    return false;
}

//connect
if(connect(fd, servinfo->ai_addr, servinfo->ai_addrlen) < 0) {
    printf("\nclient connection failure %m", errno);
    return false;
}

Я знаю, что это должно быть просто, но я не могу понять, как изменить IP-адреса, чтобы заставить их работать. Я попытался установить IP-адрес сервера в кавычках в этих строках - if ((status = getaddrinfo ("127.0.0.1", порт, & hints, & servinfo))! = 0) а также разъединить ( "127.0.0.1");

, а затем измените адрес в коде клиента на IP-адрес клиентского компьютера в этой строке - if ((status = getaddrinfo ("127.0.0.1", порт, & hints, & servinfo))! = 0)

Всякий раз, когда я делаю это, он говорит мне, что соединение отказано. Я также попытался сделать противоположный способ размещения адреса сервера в строке клиента и адреса клиента в строках сервера вместе с несколькими другими попытками. На данный момент я чувствую, что я просто догадываюсь. Так может кто-нибудь, пожалуйста, помогите мне понять, как изменить это с использования локального адреса с одним компьютером на подключение двух компьютеров? Любая помощь приветствуется.

Ответы [ 3 ]

1 голос
/ 11 августа 2011

Основная проблема в том, что вы помещаете AI_PASSIVE в код своего клиента.AI_PASSIVE предназначен только для серверов (вот что он сигнализирует).

Кроме того, на стороне сервера, прежде всего, не следует вызывать unlink.Это только для сокетов AF_UNIX, а не AF_INET.Во-вторых, вам не нужно помещать «127.0.0.1» в строку getaddrinfo на стороне сервера.Лучше использовать NULL для привязки ко всем доступным адресам.

Если вы измените эти вещи, я считаю, что ваш код должен работать.Однако на самом деле вы должны зацикливаться на результате getaddrinfo, используя указатель ai_next, и пытаться соединиться с каждым результатом, используя первый успешный результат.

1 голос
/ 11 августа 2011

Во-первых, unlink("127.0.0.1"); здесь совершенно не так, не делайте этого.

Затем у вас есть два компьютера, соединенные некоторой сетью.Оба должны иметь IP-адреса.Замените 127.0.0.1 IP-адресом сервера на клиенте и на сервере.Сервер не должен знать адрес клиента заранее - он получит эту информацию из вызова accept(2).Клиенту нужен адрес сервера, чтобы знать, где подключиться.Серверу нужен собственный адрес для вызова bind(2).

0 голосов
/ 11 августа 2011

Connection Refused обычно означает, что ваш клиент получил RST на его SYN.Это чаще всего вызвано отсутствием прослушивающего сокета на сервере, к порту, к которому вы пытаетесь подключиться.

  1. Запустите сервер
  2. В CLI введите netstat -ant.Видите ли вы запись, которая находится в состоянии LISTEN на вашем порту?

Что-то вроде:

tcp4       0      0  *.3689                 *.*                    LISTEN  

Могу поспорить, что у вас нет, и, следовательно, возникли проблемы с вашим серверомгнездо для прослушивания.Я также держу пари, что изменения, которые вы внесли в эту строку:

if ((status = getaddrinfo("127.0.0.1", port, &hints, &servinfo)) != 0) {

были не совсем правы.Попробуйте изменить этот IP-адрес на 0.0.0.0 на сервере, чтобы он связывался с любым IP-адресом в системе.На клиенте эта строка должна иметь IP-адрес сервера.Вам также следует удалить вызов unlink() на сервере;ненужным.

Если у вас действительно есть гнездо для прослушивания, то, вероятно, между вашими блоками есть брандмауэр или что-то, что блокирует SYN.Попробуйте ввести service iptables stop в CLI обеих систем.

...