简体   繁体   English

TCP服务器和客户端的问题

[英]problem with tcp server and client

Hii all, I have already created some programs related to client and server. 大家好,我已经创建了一些与客户端和服务器相关的程序。 Today it was my sessional[practical exam] of Client-server technology. 今天,这是我的客户端-服务器技术的期课[实践考试]。

Problem was: i was to add two no's at server sent from client and result back to client. 问题是:我要在客户端发送的服务器上添加两个No,然后将结果返回给客户端。

I tried this solution but some strange solution was there: Server.java 我尝试了此解决方案,但那里有一些奇怪的解决方案:Server.java

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

public class Server{
    public static void main(String args[]) throws Exception{
        ServerSocket s = new ServerSocket(7896);
        Socket cs = s.accept();
        BufferedReader br = new BufferedReader(new InputStreamReader(cs.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(cs.getOutputStream()));
        bw.write(br.read() + br.read());
    }
}

Client.java Client.java

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

public class Client{
public static void main(String args[]) throws Exception{
    Socket s = new Socket("localhost", 7896);
    BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
    bw.write(3);
    bw.write(4);
    System.out.println("Output is: " + br.read());
}
}

when i ran it on dos prompt i got two blank screens; 当我在dos提示符下运行它时,我得到两个空白屏幕; one at client site and one at server site(which was a bit surprising). 一个在客户端站点,一个在服务器站点(这有点令人惊讶)。 then i closed server then suddenly i got error msg at client something like connection closed. 然后我关闭了服务器,然后突然在客户端出现错误msg,例如关闭了连接。

Then i ran same program on my ubuntu linux with same jdk 1.6 as it was in windows, and here also blank screens but when i closed server i got: 然后我在ubuntu linux上以与Windows中相同的jdk 1.6运行了相同的程序,这里的屏幕也空白,但是当我关闭服务器时,我得到了:

Output is: -1

Although in exam i done this using DataOutputStream and DataInputStream. 尽管在考试中我使用DataOutputStream和DataInputStream做到了这一点。

But why the above code is not working. 但是为什么上面的代码不起作用。

Can Anyone explain what is happening in the code there. 任何人都可以解释那里的代码中发生了什么。

Thanks 谢谢

A few comments which might help you reach the correct answer: 一些评论可能会帮助您获得正确的答案:

  • The server code as it is can accept only a single client request since the accept() call isn't present in an infinite loop. 由于无限循环中不存在accept()调用,因此服务器代码本身只能接受单个客户端请求。
  • When using buffered streams, make sure you always flush the OuputStream/Writer to ensure that the data is actually written to the client instead of just lying around in the buffer. 使用缓冲流时,请确保始终刷新OuputStream/Writer以确保将数据实际写入客户端,而不是仅仅躺在缓冲区中。
  • DataInput/OutputStream is absolutely required (or any other approach which logically reads the "number" string and converts it to an appropriate representation which can be added) since just reading from the BufferedReader doesn't fetch you the "numbers". 的DataInput / OutputStream中是绝对必要的(或任何其他方式在逻辑上读取“数字”的字符串,并将其转换为可添加适当的表示),因为从刚刚读书 BufferedReader不接你的“数字”。

But the question is, why flushing is required? 但是问题是,为什么需要冲洗? To answer this question, one has to understand why "buffering" is used in the first place. 为了回答这个问题,必须理解为什么首先要使用“缓冲”。 Why bother wrapping your streams in another stream when you can directly write to your stream? 直接写到流中时,为什么还要麻烦将流包装到另一个流中? The reason is that I/O operations are really expensive (at least when compared to accessing your RAM or CPU cache/registers). 原因是I / O操作确实很昂贵(至少与访问RAM或CPU缓存/寄存器相比)。 Frequent writes/reads accessing/writing small chunks of data to the HDD can choke up your HDD and bring down the overall performance of your application. 频繁的写入/读取访问/将小数据块写入HDD可能会阻塞您的HDD,并降低应用程序的整体性能。

So what's the solution? 那么解决方案是什么? Write data to the HDD less frequently. 将数据写入硬盘的频率降低。 Two ways this can be achieved: 有两种方法可以实现:

  1. Manually allocate a large byte array and fill up the entire array in a single read. 手动分配一个大字节数组,并在一次读取中填满整个数组。 This is way better than single byte reads. 这比单字节读取更好。 The byte array size does require tuning as per your application needs but for general purposes 8K should be good to go. 字节数组的大小确实需要根据您的应用程序需求进行调整,但对于一般用途,最好使用8K。
  2. Use a buffered stream. 使用缓冲的流。 This has the advantage of not exposing the clients to the low level details. 这样做的好处是不会向客户公开低级详细信息。 Your application can use the "stream" as it sees fit (continuously writing single bytes to it) and the stream would assume the complete responsibility of flushing the buffered data when it sees fit (this depends on the buffer size which you set when creating a buffered stream). 您的应用程序可以使用它认为合适的“流”(连续向其中写入单个字节),并且该流将完全负责在其认为合适时刷新 缓冲的数据(这取决于您在创建缓冲区时设置的缓冲区大小)。缓冲的流)。

Though the explanation was HDD specific, the same applies to other types of stream like in your case socket. 尽管解释是特定于HDD的,但同样适用于其他类型的流,例如您的情况套接字。

TL;DR: Buffering improves IO throughput/performance. TL; DR:缓冲可提高IO吞吐量/性能。 :) :)

write() will buffer input so it does not need to do lots of small writes. write()将缓冲输入,因此不需要进行大量的小写操作。 Since you are not writing much to the buffer, it is probably still there and not written out yet. 由于您没有向缓冲区写入太多内容,因此它可能仍然存在并且尚未写出。 Calling flush() will force it to write out the buffer. 调用flush()将强制其写出缓冲区。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM