java - 为什么客户端看不到服务器发送的第一条消息?

标签 java sockets client-server

首先,这是我的服务器。请看这部分

if(clients.size() == 2){

    sendStartSignal();
    break;

}

在上面的部分中,当至少有两个客户端连接到服务器时,我发送一个启动信号“start”字符串。

服务器代码从这里开始......

#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <iostream>
#include <pthread.h>
#include <vector>
#include <sys/fcntl.h>

using namespace std;


void * handle_client(void * ptr);


void sendStartSignal();


struct thdata{

    int client_no;

};


vector<pthread_t *> clients;
vector<int> client_nos;

int main(int argc, char **argv)
{
    struct sockaddr_in server_addr,client_addr;
    socklen_t clientlen = sizeof(client_addr);
    int option, port, reuse;
    int server, client;
    int nread;

    // setup default arguments
    port = 3000;

    // process command line options using getopt()
    // see "man 3 getopt"
    while ((option = getopt(argc,argv,"p:")) != -1) {
        switch (option) {
            case 'p':
                port = atoi(optarg);
                break;
            default:
                cout << "server [-p port]" << endl;
                exit(EXIT_FAILURE);
        }
    }

      // setup socket address structure
    memset(&server_addr,0,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    server_addr.sin_addr.s_addr = INADDR_ANY;

      // create socket
    server = socket(PF_INET,SOCK_STREAM,0);
    if (!server) {
        perror("socket");
        exit(-1);
    }

      // set socket to immediately reuse port when the application closes
    reuse = 1;
    if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) {
        perror("setsockopt");
        exit(-1);
    }

      // call bind to associate the socket with our local address and
      // port
    if (bind(server,(const struct sockaddr *)&server_addr,sizeof(server_addr)) < 0) {
        perror("bind");
        exit(-1);
    }

      // convert the socket to listen for incoming connections
    if (listen(server,SOMAXCONN) < 0) {
        perror("listen");
        exit(-1);
    }



      // accept clients
    while ((client = accept(server,(struct sockaddr *)&client_addr,&clientlen)) > 0) {


        //make the clients non blocking
        fcntl(client, F_SETFL, O_NONBLOCK);



        pthread_t* th = new pthread_t;
        thdata* data = new thdata;
        data->client_no = client;


        clients.push_back(th);
        client_nos.push_back(client);


         pthread_create(th, NULL, &handle_client, (void *) data);


        if(clients.size() == 2){

        sendStartSignal();
        break;

        }

    }





for(int i=0;i<clients.size();i++){

    pthread_join(*clients[i], NULL);

}




}



void sendStartSignal(){


    char *buf;
    int buflen;
    int nread;
    // allocate buffer
    buflen = 1024;
    buf = new char[buflen+1];


    buf[0] = 's';
    buf[1] = 't';
    buf[2] = 'a';
    buf[3] = 'r';
    buf[4] = 't';
    buf[5] = 0;


            for(int i = 0;i<clients.size();i++) {

             send(client_nos[i], buf, 6, 0);


            }


}



void * handle_client(void * ptr){


        thdata * data = (thdata*) ptr;


        char *buf;
        int buflen;
        int nread;
        // allocate buffer
        buflen = 1024;
        buf = new char[buflen+1];


        int client_no = data->client_no;



        // loop to handle all requests
        while (1) {

              // read a request
            memset(buf,0,buflen);

            nread = recv(client_no,buf,buflen,0);


            if(nread >= 0){


                if(nread == 0) {

                    int index_to_delete = -1;

                    for(int i=0;i<client_nos.size();i++){

                        if(client_nos[i] == client_no){

                            index_to_delete = 0;
                            break;

                        }

                    }

                    clients.erase(clients.begin() + index_to_delete);
                    client_nos.erase(client_nos.begin() + index_to_delete);


                    break;
                }



            for(int i = 0;i<clients.size();i++) {


                if (client_nos[i] != client_no){
                    send(client_nos[i], buf, nread, 0);
                }

            }




            }


        }



}

现在,这是我的 java 客户端

请看这部分...

public static void handle_read(){


            while(true){

                         try{   

                             String line = r.readLine();
                             System.out.println(line);

                        }

                        catch(Exception e){

                          System.err.println(e);

                        }
                     }


}

在上面的部分中,它是一个仅读取来自服务器的传入消息的线程。现在,我的问题是,正如您在服务器代码中看到的那样,一旦建立两个连接,“开始”信号就会发送到客户端......现在,只要两个客户端连接到服务器,客户端就不会打印开始服务器...在我向服务器发送一些消息后,它只打印“开始”。为什么会这样?

客户端从这里开始......

import java.io.*;
import java.net.*;

import java.util.*;

public class Client 
   {



   public static BufferedReader r;
   public static PrintWriter w;


    public static void main(String[] args){


            try
            {
                Socket s = new Socket("localhost", 3000);

                r = new BufferedReader(new InputStreamReader(s.getInputStream()));
                w = new PrintWriter(s.getOutputStream(), true);
                BufferedReader con = new BufferedReader(new InputStreamReader(System.in));



                Thread t1 = new Thread(){

                    public void run(){

                        handle_read();

                    }

                };


                Thread t2 = new Thread(){

                    public void run(){

                        handle_write();

                    }


                };


                t1.start();
                t2.start();

                t1.join();
                t2.join();


                System.out.println("Exiting .... ");





            }
            catch (Exception err)
            {
                System.err.println(err);
            }






}


public static void handle_read(){


            while(true){

                    try{    
                          String line = r.readLine();
                          System.out.println(line);
                        }

                        catch(Exception e){

                             System.err.println(e);

                        }
                    }



}


public static void handle_write(){



            while(true){

                         try{

                            Scanner scan = new Scanner(System.in);
                            String s = scan.next();

                            w.println(s);

                         }
                         catch(Exception e){

                             System.err.println(e);

                        }   

                     }


}



    }

谢谢!

最佳答案

您正在发送此消息:

buf[0] = 's';
buf[1] = 't';
buf[2] = 'a';
buf[3] = 'r';
buf[4] = 't';
buf[5] = 0;

那么你正在用这段代码阅读它

String line = r.readLine();

这似乎不匹配。您没有发送一行,但您正在尝试读取一行。

以换行符“\n”结束您发送的消息

关于java - 为什么客户端看不到服务器发送的第一条消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20295191/

相关文章:

java - 如何使用工厂为特定主题配置 Spring Kafka Listener?

java - 如何在 if 语句后将字符串添加在一起

java - 无需调用 Session 对象上的 save() 方法即可持久保存对象

database - 路由时应该保留数据吗?

javascript - 检测变量更改并执行回调的最有效方法

java - 更新/检索/插入日期字段

php - 用于连续检查 MYSQL 数据库的 Web Worker AJAX 或 Web 套接字?

java - 我们需要在我们的 UML 类图中添加接口(interface) Runnable 吗?

java - Socket.close() 在 Socket.connect() 期间无效

Java - ByteArrayOutputStream 替换,但仅适用于 1 个值