2015-05-23 2 views
2

Я хотел бы извиниться за мой английский. Это не мой родной язык.DataOutputStream отправляет неправильные данные

Я пытаюсь написать простой TCP-сервер и клиент. У меня проблема с отправкой номера с клиента на сервер. Вот код со стороны клиента:

public class ConnectionHandler { 
    private InetAddress address; 
    private int port; 

    private Socket socket; 
    private DataOutputStream dos; 
    private DataInputStream dis; 

    public ConnectionHandler(String ipAddress, String port) { 
    try { 
     address = InetAddress.getByName(ipAddress); 
     this.port = Integer.parseInt(port); 
     connectionHandle(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 
    private void connectionHandle() { 
    try { 
     socket = new Socket(address, port); 
     dos = new DataOutputStream(socket.getOutputStream()); 
     dis = new DataInputStream(socket.getInputStream()); 

     getCatalogueList(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    private void getCatalogueList() { 
    try { 
     dos.writeInt(1); 
     sendFile(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 
    public void sendFile() { 
    try{ 
     dos.writeInt(2); 
    } catch(Exception e) { 
     e.printStackTrace(); 
    } 
    } 

Все отлично работает, когда я отправляю номер 1 в getCatalogueList(), но затем в SendFile Я пытаюсь отправить номер 2, но мой сервер получает 0 Я проверил это, если я отправляю номера одной функцией:

private void getCatalogueList() { 
    dos.writeInt(1); 
    dos.writeInt(2); 
} 

все работает. Проблема заключается только в том, что я использую две разные функции.

Если кто-то может помочь мне, как предотвратить это и объяснить мне, почему это происходит, я буду очень благодарен.


код сервера (это в C, я использую BSD-сокетов)

int handleConnection(int clientSocket) { 
    short connectionClosed = False; 
    long action; 

    while(!connectionClosed) { 
    recv(clientSocket, &action, sizeof(int), 0); 
    action = ntohl(action); 
    printf("%i\n", action); 
    } 
    return 0; 
} 

int main() { 
    const int port = 8080; 
    const int maxConnection = 20; 

    int listeningSocket, clientSocket; 

    struct sockaddr_in server, client; 
    struct hostent *host; 
    socklen_t sin_size = sizeof(struct sockaddr_in); 

    char myhostname[1024]; 

    listeningSocket = socket(PF_INET, SOCK_STREAM, 0); 
    gethostname(myhostname, 1023); 
    host = gethostbyname(myhostname); 

    server.sin_family = AF_INET; 
    server.sin_port = htons(port); 
    server.sin_addr = *(struct in_addr*) host->h_addr; 

    if (bind(listeningSocket, (struct sockaddr*) &server, sizeof(struct sockaddr)) == -1) { 
    return -1; 
    } 

    listen(listeningSocket, maxConnection); 
    while(True) { 
    sin_size = sizeof(struct sockaddr_in); 
    clientSocket = accept(listeningSocket, (struct sockaddr*) &client, &sin_size); 
    if(fork() == 0) { 
     handleConnection(clientSocket); 
     close(clientSocket); 
     exit(0); 
    } 
    else { 
     printf("Waiting for connection.\n"); 
     continue; 
    } 
    } 
    return 0; 
} 
+1

(1) показать код сервера, а также , (2) - это ваш * точный * код, или вы создали выдержку из более крупной программы, и (3) вы подклассифицируете «ConnectionHandler»? – kdgregory

+0

Я добавил код сервера. Это часть более крупной программы (клиент имеет графический интерфейс в качелях), но это все части, ответственные за соединение между сервером и клиентом. Я только удалил несколько строк, отвечающих за отправку (на сервере) и получение (на клиентском) дереве файлов. Я не думаю, что они имеют какой-либо смысл здесь, потому что я использую DataInputStream, а не Output для этого. Я могу вставить их, если это поможет. Мой ConnectionHandler не расширяет какой-либо высший класс, если это то, что вы подразумеваете под подклассом (я не уверен, правильно ли я понял u). – Ironus

ответ

1

Вы не обращая внимание на количество возвращенное recv(). Это может быть -1, что указывает на страницу ошибки, или ноль , указывающий конец потока или любое положительное значение от 1 до sizeof int включительно. Вместо этого вы предполагаете, что он заполнил буфер.

Это не имеет ничего общего с DataOutputStream.

Вы также утечкой клиентские сокеты в родительском процессе, а не проверка на наличие ошибок с socket() или accept() или listen().

+0

Изменение recv на if (recv (clientSocket, & action, sizeof (int), 0)! = -1) не имеет никакого эффекта. Я все еще получаю 0 при попытке получить 2 – Ironus

+0

Это не тест для трех разных возможностей. Нет правильного способа сделать это, не сохраняя результат в переменной. – EJP

+0

Я не совсем уверен, что делать. Я имею в виду, я посылаю int от клиента и получаю int на сервере. Теперь, если я правильно понял вас, я должен сделать еще один recv для другой переменной, и тогда все должно быть в порядке? – Ironus

Смежные вопросы