Невозможно запустить TCP-сервер на iOS, сотовая связь

Я пытаюсь запустить TCP-сервер на iOS от сотовой связи. Для того чтобы задать этот вопрос, я написал эту очень упрощенную версию сервера и клиента на C, используя socket/bind/listen/accept/etc. Это прекрасно работает, когда я запускаю серверную программу с сервера. Когда я запускаю серверную программу из приложения iOS через Cellular (без Wi-Fi), клиент никогда не подключается к серверу. Вот мой код:

Сервер:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <pthread.h>

#include "tcp_server_IPv4.h"

#define SZ_SOCKADDR_IN sizeof(struct sockaddr_in)

void pfail(char *w) {
    printf("pfail %s\n", w);
    perror(w);
    exit(1);
}

void *tcp_server_IPv4_thread_routine(void *arg) {

    int tcp4_sockfd = 0, tcp4_new_fd = 0;
    char wes[64];
    tcp4_sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in their_addr = {0};

    struct sockaddr_in serv_addr = {0};
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(0);

    int br = bind(tcp4_sockfd, (struct sockaddr*)&serv_addr, SZ_SOCKADDR_IN);
    if (br ==  -1) {
        pfail("PROBLEM BINDING");
    }

    int lr = listen(tcp4_sockfd, 5);
    if (lr == -1) {
        pfail("PROBLEM LISTENING");
    }

    socklen_t gsn_len = sizeof(serv_addr);
    int gsn = getsockname(tcp4_sockfd, (struct sockaddr*)&serv_addr, &gsn_len);
    if (gsn == -1) pfail("getsockname");

    inet_ntop(AF_INET, &serv_addr, wes, sizeof(wes));
    printf("start listening on (%s) port (%d)...", wes, ntohs(serv_addr.sin_port));
    int tcp_running = 1;
    while (tcp_running) {  // main accept() loop
        socklen_t sin_size = sizeof their_addr;
        tcp4_new_fd = accept(tcp4_sockfd, (struct sockaddr *)&their_addr, &sin_size);
        if (tcp4_new_fd == -1) {
            perror("accept");
            continue;
        }

        inet_ntop(their_addr.sin_family, &their_addr.sin_addr, wes, sizeof wes);
        printf("server: got connection from %s\n", wes);

        if (!fork()) { // this is the child process
            close(tcp4_sockfd); // child doesn't need the listener
            if (send(tcp4_new_fd, "Hello, world!", 13, 0) == -1)
                perror("send");
            close(tcp4_new_fd);
            exit(0);
        }
        close(tcp4_new_fd);  // parent doesn't need this
    }
    pthread_exit("exiting fire_up_tcp thread normally");
}

void start_tcp_server_IPv4() {
    pthread_t tcpt4;
    char *w4 = "TCP server IPv4 thread";
    int pr4 = pthread_create(&tcpt4, NULL, tcp_server_IPv4_thread_routine, (void *)w4);
    if (pr4) pfail("create thread for fire_up_tcp_server_v4");
}

Клиент:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#define PORT_NUMBER 57020
#define SERVER_ADDRESS  "70.208.71.248"

#define MAXDATASIZE 200 // max number of bytes we can get at once 

int main(int argc, char *argv[]) {
    int sockfd, numbytes;  
    char buf[MAXDATASIZE];
    char ip_str[INET6_ADDRSTRLEN];

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("client: socket");
        exit(1);
    }
    struct sockaddr_in sa_server = {0};
    sa_server.sin_family = AF_INET;
    inet_pton(AF_INET, SERVER_ADDRESS, &(sa_server.sin_addr));
    sa_server.sin_port = htons(PORT_NUMBER);

    inet_ntop(AF_INET, &sa_server.sin_addr, ip_str, sizeof ip_str);

    printf("Try connecting to (%s)(%d)\n", ip_str, ntohs(sa_server.sin_port));

    if (connect(sockfd, (struct sockaddr *)&sa_server, sizeof(struct sockaddr_in)) == -1) {
        fprintf(stderr, "Error on connect --> %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    puts("CLIENT::Connection successful.");

    char fr[128];
    sprintf(fr, "Some text here to send");
    if (send(sockfd, fr, sizeof fr, 0) < 0) {
        fprintf(stderr, "Error on send --> %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    if ((numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {
        perror("recv");
        exit(1);
    }

    buf[numbytes] = '\0';

    printf("client: received '%s'\n",buf);

    close(sockfd);
    return 0;
}

Результаты запуска getifaddrs() на устройстве iOS. Все адреса pdp_ip работают и работают:

(interface)(family)(ip)

(lo0)(2)(127.0.0.1)
(lo0)(30)(::1)
(lo0)(30)

(pdp_ip0)(2)(100.114.61.107)
(pdp_ip0)(30)(fe80::4d5:31ee:ba73:d63a)
(pdp_ip0)(30)(2600:1001:b101:600d:1076:2a12:b461:2a02)
(pdp_ip0)(30)(2600:1001:b101:600d:89e3:c982:c32a:b6b2)

(pdp_ip2)(30)(fe80::18b6:a5a7:33a2:13f6)
(pdp_ip2)(30)(2600:1001:812f:cec5:49:69a:d1b9:cc47)
(pdp_ip2)(30)(2600:1001:812f:cec5:e936:25c5:702:e067)
(pdp_ip2)(30)(2600:1001:812f:cec5:48de:1765:5cb5:d56c)

(en2)(30)(fe80::10d5:2496:594f:ff72)
(en2)(2)(169.254.249.210)
(ipsec1)(30)(fe80::26f0:94ff:fe9a:50bc)
(utun0)(30)(fe80::99a1:9bf7:428e:8166)
(utun1)(30)(fe80::4b1d:be95:bbf2:bf02)
(utun2)(30)(fe80::1748:1a1a:c5ee:bda9)
(utun3)(30)(fe80::d3c1:79bc:7613:ffb)
(utun4)(30)(fe80::d3c8:e837:ba74:67dc)

0 ответов

Другие вопросы по тегам