Сокет программирования, C-Java - PullRequest
0 голосов
/ 20 мая 2011

Эй, ребята, я искал некоторую информацию о программировании сокетов в течение нескольких часов прямо сейчас и до сих пор не могу понять, как решить мою проблему.

Меня попросили сделать следующее:

Сервер принимает дейтаграмму UDP через порт 8080, отправленную клиентом, а в дейтаграмме клиент отправляет массив символов, представляющий число (9090) Сервер создаст новый сокет, установит TCP-соединение с клиентом в порту 9090. Через соединение tcp сервер считывает имя, отправленное клиентом.

Нас просят написать клиента, способного выполнять эти задачи на C, сервер уже выполнен и находится в файле .jar

Программа должна работать следующим образом: ./client SERVER_NAME

и сервер: java -jar server.jar

Я дошел до этого ... с мыслью, что она охватывает первую часть (отправка пакета udp), но не совсем уверен, как следовать:

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

#define SERVERPORT "8080"    // the port users will be connecting to

int main(int argc, char *argv[])
{
    int sockfd;
    struct addrinfo hints, *servinfo, *p;
    int rv;
    int numbytes;

    if (argc != 2) {
        fprintf(stderr,"usage: talker hostname\n");
        exit(1);
    }

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;

    if ((rv = getaddrinfo(argv[1], SERVERPORT, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    // loop through all the results and make a socket
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ((sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1) {
            perror("talker: socket");
            continue;
        }
        break;
    }

    if (p == NULL) {
        fprintf(stderr, "talker: failed to bind socket\n");
        return 2;
    }

    int num = 9090;
    num = htonl(num);
    if ((numbytes = sendto(sockfd, num, sizeof(num), 0,
             p->ai_addr, p->ai_addrlen)) == -1) {
        perror("talker: sendto");
        exit(1);
    }

1 Ответ

0 голосов
/ 20 мая 2011

Предоставляет ли java-сервер какие-либо отзывы, которые вы можете использовать для проверки вашего UDP на данный момент? Если это так, я бы проверил и действовал следующим образом.

Настройте отдельный сокет для установления TCP-соединения. В Интернете есть много ресурсов, показывающих, как это сделать (пример Google c tcp client). Поскольку UDP является ненадежным протоколом с максимальными усилиями, вам понадобится метод для повторной попытки подключения. Одним из решений может быть зацикливание, отправка дейтаграммы UDP и попытка TCP-соединения на другом сокете, пока соединение не будет установлено (или не будет достигнут какой-либо другой предел времени или максимальный предел повторных попыток).

// setup TCP socket to connect to your chosen port 'num'...
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
// handle error

struct sockaddr_in tcpServAddr;
memset(&tcpServAddr, 0, sizeof(tcpServAddr));
tcpServAddr.sin_family      = AF_INET;
tcpServAddr.sin_addr.s_addr = inet_addr(<insert server ip here>);
tcpServAddr.sin_port        = htons(num);

const int iMaxTries = 10;
int iTryCount = 0;
bool bConnected = false;
while(!bConnected && (iTryCount < iMaxTries)) {
  // using your bock from above:
  if ((numbytes = sendto(sockfd, num, sizeof(num), 0,
             p->ai_addr, p->ai_addrlen)) == -1) {
        perror("talker: sendto"); // may want to output strerr(errno) for more information
        break; // something is wrong if we can't send UDP. bail and figure that out
  }

  ++iTryCount;

  // try the TCP connection on the target port
  if (connect(tcpSockFd, (struct sockaddr *) &tcpServAddr, sizeof(tcpServAddr)) == 0) {
    bConnected = true;
  } else {
    // report error
  }
}

if (bConnected) {
   // send(...) name on tcpSockFd
}
// cleanup sockets

Ничего из вышеперечисленного не проверено, но, надеюсь, оно даст вам общее руководство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...