java - 简单的客户端服务器程序

标签 java network-programming

我制作了一个基于 TCP/IP 的基本项目,其中服务器监听客户端,然后提供传入数据的大写语句。

服务器.java:

import java.io.*;
import java.net.*;
public class Server 
{

    public static void main(String[] args) throws Exception
    {
        ServerSocket ss = new ServerSocket(7948);
        Socket s= ss.accept();
        System.out.print("Server connected\n");

        BufferedInputStream bis = new BufferedInputStream (s.getInputStream());
        BufferedOutputStream bos = new BufferedOutputStream (s.getOutputStream());

        while(true)
        {
            int a = bis.available();
            byte b[] = new byte[a];
            bis.read(b);
            String str = new String(b);
            str = str.toUpperCase();
            b = str.getBytes();
            bos.write(b,0,b.length);
            bos.flush();

            if(str.equals("BYE"))
                break;
            else
                continue;
        }
        System.out.print("\nServer Disconnecting");
        String str = "Adios Amigo";
        bos.write(str.getBytes());
        bos.flush();

        bis.close();
        bos.close();
        ss.close();
        s.close();
    }
}

客户端.java:

import java.io.*;
import java.net.*;
public class Client 
{

    public static void main(String[] args) throws Exception
    {
        BufferedReader clientStream = new BufferedReader(new InputStreamReader(System.in));
        String str; 
        int a;
        byte[] b;

        Socket s = new Socket(InetAddress.getLocalHost(), 7948);

        BufferedOutputStream bos = new BufferedOutputStream (s.getOutputStream());
        BufferedInputStream bis = new BufferedInputStream (s.getInputStream());

        one:while(true)
        {
            str = clientStream.readLine();
            b =str.getBytes();
            bos.write(b);
            bos.flush();

            a=bis.available();
            b = new byte[a];
            bis.read(b);
            str = new String (b);
            str.trim();
            System.out.print("The server says: "+str);
            if (str.equals("BYE"))
            {
                bis.read(b);
                str = new String (b);
                System.out.print("The server says: "+str);
                break one;
            }
        }

        s.close();
        clientStream.close();
        bos.close();
        bis.close();
    }
}

除了一个问题,程序运行正常,客户端的输出在两次输入之后。这意味着我必须从客户端提供两个输入以获得第一个输出,并且这种情况会继续。我无法跟踪错误。 任何人都可以帮忙吗?

最佳答案

在客户端,你向服务器发送数据,然后立即调用a.available()——这个函数不等待服务器发送数据。由于在调用 .available() 时服务器不太可能已经响应数据,因此该函数返回零。

因此,您的字节数组 b(请在未来使用更具描述性的变量名称)的长度为零。

创建大小为零的数组后,您最终可以通过调用 bis.read() 等待数据 - .read() 是一个阻塞 调用。它将等待来自服务器的数据。该数据实际上并未读取,因为您正在读取的数组大小为零。这导致打印出一个空字符串。

下面的代码将解决这个问题,但为了将来,我不建议使用 .available() - 根据我的经验,它相当不可靠。您应该通过简单地尝试读取数据来检查数据是否可用。

客户端.java:

    one:while(true)
    {
        str = clientStream.readLine();
        b =str.getBytes();
        bos.write(b);
        bos.flush();

        while (bis.available() <= 0)
        {
            // wait for data!
        }

        a=bis.available();
        b = new byte[a];
        bis.read(b);
        str = new String (b);
        str.trim();
        System.out.print("The server says: "+str);
        if (str.equals("BYE"))
        {
            bis.read(b);
            str = new String (b);
            System.out.print("The server says: "+str);
            break one;
        }
    }

关于java - 简单的客户端服务器程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15171496/

相关文章:

Java UDP 数据报包 - 切片数据以适应缓冲区大小

golang : client tls. Conn 关闭钩子(Hook)

java - Kotlin + SpringBoot : DI lateinit property service has not been initialized

java - 将节点插入链表中间,不小心也插入了空节点

java - H2 数据库 - CSVREAD - 将时间戳从 csv 读取到时间戳列

c - c中结构的定义

java - 如何在Java中的Web服务中接收 HashMap ?

java - 跨平台比较文件内容

java - 没有收到服务器的响应

network-programming - 绑定(bind)错误 : Address already in use