hqt*_*hqt 12 java sockets inputstream outputstream
我已经使用创建了一个服务器ServerSocket
.之后,我创建了Client Socket
,并连接到此服务器.
之后,我使用InputStream执行"一些东西",并从Socket Object获取OutputStream.但是,我真的不太了解inputStream和outputStream.这是我的简单代码:
private Socket sock = null;
private InputStream sockInput = null;
private OutputStream sockOutput = null;
...
String msg = "Hello World";
byte[] buffer = null;
try {
sockOutput.write(msg.getBytes(), 0, test.length());
sockOutput.write("Hello StackOverFlow".getBytes(), 0, test.length());
buffer = new byte[test.length()];
sockInput.read(buffer, 0, test.length());
System.out.println(new String(buffer));
sockInput.read(buffer, 0, test.length());
System.out.println(new String(buffer));
} catch (IOException e1) {
e1.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
结果将是:"Hello World"和"Hello StackOverFlow".
这是服务器端代码:
private int serverPort = 0;
private ServerSocket serverSock = null;
public VerySimpleServer(int serverPort) {
this.serverPort = serverPort;
try {
serverSock = new ServerSocket(this.serverPort);
}
catch (IOException e){
e.printStackTrace(System.err);
}
}
// All this method does is wait for some bytes from the
// connection, read them, then write them back again, until the
// socket is closed from the other side.
public void handleConnection(InputStream sockInput, OutputStream sockOutput) {
while(true) {
byte[] buf=new byte[1024];
int bytes_read = 0;
try {
// This call to read() will wait forever, until the
// program on the other side either sends some data,
// or closes the socket.
bytes_read = sockInput.read(buf, 0, buf.length);
// If the socket is closed, sockInput.read() will return -1.
if(bytes_read < 0) {
System.err.println("Server: Tried to read from socket, read() returned < 0, Closing socket.");
return;
}
System.err.println("Server: Received "+bytes_read
+" bytes, sending them back to client, data="
+(new String(buf, 0, bytes_read)));
sockOutput.write(buf, 0, bytes_read);
// This call to flush() is optional - we're saying go
// ahead and send the data now instead of buffering
// it.
sockOutput.flush();
}
catch (Exception e){
System.err.println("Exception reading from/writing to socket, e="+e);
e.printStackTrace(System.err);
return;
}
}
}
public void waitForConnections() {
Socket sock = null;
InputStream sockInput = null;
OutputStream sockOutput = null;
while (true) {
try {
// This method call, accept(), blocks and waits
// (forever if necessary) until some other program
// opens a socket connection to our server. When some
// other program opens a connection to our server,
// accept() creates a new socket to represent that
// connection and returns.
sock = serverSock.accept();
System.err.println("Server : Have accepted new socket.");
// From this point on, no new socket connections can
// be made to our server until we call accept() again.
sockInput = sock.getInputStream();
sockOutput = sock.getOutputStream();
}
catch (IOException e){
e.printStackTrace(System.err);
}
// Do something with the socket - read bytes from the
// socket and write them back to the socket until the
// other side closes the connection.
handleConnection(sockInput, sockOutput);
// Now we close the socket.
try {
System.err.println("Closing socket.");
sock.close();
}
catch (Exception e){
System.err.println("Exception while closing socket.");
e.printStackTrace(System.err);
}
System.err.println("Finished with socket, waiting for next connection.");
}
}
public static void main(String argv[]) {
int port = 54321;
VerySimpleServer server = new VerySimpleServer(port);
server.waitForConnections();
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:
当我使用时sockOutput.write
,我可以回复这些消息sockInput.read
.那么,那些消息已被保存,对吧?如果这是真的,它是否保存在我创建的服务器上,或者只保存在其他一些内容中Socket Object
.
如果我已经写入套接字字符串A1,A2,...那么我将分别收到A1,A2,...一个字符串,对吗?
DNA*_*DNA 37
套接字是一种抽象,可用于与网络中的某些内容进行通信.见下图......
在Java中,要通过套接字发送数据,从中获取OutputStream
(1),并写入OutputStream
(输出一些数据).
要从套接字读取数据,您可以InputStream
从第二个流中获取数据并读取输入.
您可以将流视为连接到墙上插座的一对单向管道.在墙的另一边发生的事情不是你的问题!
在您的情况下,服务器有另一个套接字(连接的另一端)和另一对流.它使用它的InputStream
(2)从网络读取,并且它OutputStream
(3)通过网络将相同的数据写回客户端,客户端通过其InputStream
(4)完成往返再次读取它.
Client Server
1. OutputStream -->\ /--> 2. InputStream -->
Socket <--> network <--> ServerSocket |
4. InputStream <--/ \<--3. OutputStream <--
Run Code Online (Sandbox Code Playgroud)
更新:回复评论:
请注意,流和套接字只发送原始字节; 他们在这个抽象层面上没有"信息"的概念.因此,如果您发送X个字节和另外X个字节,然后读取X个字节并读取另外X个字节,那么您的系统就像有两个消息一样,因为这就是您划分字节的方式.
如果发送X个字节和另外X个字节,然后读取长度为2X的回复,那么您可能能够读取单个组合的"消息",但正如您所注意到的,流的底层实现可以选择何时到传递大块的字节,因此它可能返回X字节,然后是X字节,稍后或一次2X,或0.5X四次......
InputStream
并且OutputStream
是两个完全独立的流.你写入的内容与你从另一个中读到的内容没有先验关系.它InputStream
为您提供服务器决定发送给您的任何数据.我还想评论你的代码:
sockOutput.write(msg.getBytes(), 0, test.length());
sockOutput.write("Hello StackOverFlow".getBytes(), 0, test.length());
Run Code Online (Sandbox Code Playgroud)
您使用字符串的长度test
(未在代码中显示),这与您作为第一个参数传递的字节数组无关.这可能会导致ArrayIndexOutOfBoundsException
或截断您的预期消息.
查看服务器端代码时,编写的代码不正确.您需要try { handleConnection(...); } finally { socket.close(); }
确保在发生错误之后以及正常完成时进行适当的清理.您的代码永远不会关闭服务器端的任何内容.
最后,最重要的是,您的整个代码的编写方式可能会导致死锁.通常,您需要一个单独的线程来读取和写入; 否则可能发生以下情况: