我想编写一个套接字客户端来向服务器发送请求并获得响应。它有效,但不对。 这是我的代码:
public String send(final String data) {
Socket client = null;
String response = null;
try {
client = new Socket(this.host, this.port);
final OutputStream outToServer = client.getOutputStream();
final DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF(data);
final InputStream inFromServer = client.getInputStream();
final DataInputStream in = new DataInputStream(inFromServer);
response = in.readUTF();
} catch (final IOException e) {
this.log.error(e);
this.log.error("Sending message to server " + this.host + ":" + this.port + " fail", e);
} finally {
if (client != null) {
try {
client.close();
} catch (final IOException e) {
this.log.error("Can't close socket connection to " + this.host + ":" + this.port, e);
}
}
}
if (StringUtils.isBlank(response)) return null;
return response;
}
问题是:我没有得到in.readUTF()
的完整回复。我总是得到一个响应,其长度与发送数据的长度(变量data
)相同。我已经使用其他GUI客户端进行了测试并得到了完整的响应。所以这不是服务器的问题。
有人知道吗,我做错了什么?
更新
感谢EJP和Andrey Lebedenko。我认为,我的问题是函数writeUTF
和readUTF
。所以我在try
块中编辑了我的代码,所以:
Charset charset = Charset.forName("ISO-8859-1");
final OutputStream outToServer = client.getOutputStream();
final DataOutputStream out = new DataOutputStream(outToServer);
out.write(data.getBytes(charset));
final InputStream inFromServer = client.getInputStream();
final BufferedReader in = new BufferedReader(new InputStreamReader(inFromServer, charset));
response = in.readLine();
它现在有效。
答案 0 :(得分:1)
如果它适用于Telnet,根据您的评论,服务器未使用readUTF()
,因此您的writeUTF()
已经错误,因此服务器不太可能使用{{1}或者,这也会使你的writeUTF()
错误。您不能任意使用这些方法:它们只能在它们之间交换数据。
我敢打赌你工作的GUI客户端也不会使用它们。
答案 1 :(得分:0)
在不知道服务器部分做什么的情况下,追踪根本原因是很困难的(如果可能的话)。所以最诚实的希望是,我会分享这段代码,我已经对上面的片段进行了测试。
package tcpsendreceive;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SendReceive {
private static final Logger log = Logger.getLogger(SendReceive.class.toString());
private final String host;
private final int port;
private Server server;
class Server extends Thread
{
private final ServerSocket serverSocket;
public Server(ServerSocket s)
{
serverSocket = s;
}
@Override
public void run()
{
Socket connection;
SendReceive.this.log.log(Level.INFO, "Server: DoubleEcho Server running on "+this.serverSocket.getLocalPort());
try{
do {
connection = this.serverSocket.accept();
SendReceive.this.log.log(Level.INFO, "Server: new connection from "+connection.getRemoteSocketAddress());
int b;
do {
DataInputStream in = new DataInputStream(connection.getInputStream());
String s = in.readUTF();
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeUTF(s+","+s); // echo it back TWICE
out.flush();
connection.shutdownOutput();
connection.close();
} while(!connection.isClosed());
}
while(true);
}
catch(IOException ioe)
{
SendReceive.this.log.log(Level.SEVERE, "IOException in server! - STOP", ioe);
}
finally {
try{
this.serverSocket.close();
} catch (Exception e) {
SendReceive.this.log.log(Level.SEVERE, "IOException closing server! - FATAL", e);
}
try{
if(!connection.isClosed())
connection.close();
} catch (Exception e) {
SendReceive.this.log.log(Level.SEVERE, "IOException closing server! - FATAL", e);
}
}
}
}
public SendReceive(String host, int port)
{
this.host = host;
this.port = port;
try{
this.server = new Server(new ServerSocket(this.port));
this.server.start();
}
catch(IOException ioe)
{
this.log.log(Level.SEVERE, "IOException while creating server! - STOP", ioe);
}
}
public String send(final String data) {
Socket client = null;
String response = null;
try {
client = new Socket(this.host, this.port);
final OutputStream outToServer = client.getOutputStream();
final DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF(data);
final InputStream inFromServer = client.getInputStream();
final DataInputStream in = new DataInputStream(inFromServer);
response = in.readUTF();
} catch (final IOException e) {
this.log.log(Level.SEVERE, "Sending message to server " + this.host + ":" + this.port + " fail", e);
} finally {
if (client != null) {
try {
client.close();
} catch (final IOException e) {
this.log.log(Level.SEVERE, "Can't close socket connection to " + this.host + ":" + this.port, e);
}
}
}
if(response == null || response.isEmpty())
return null;
return response;
}
}
试验演示
package tcpsendreceive;
public class Main {
public static void main(String[] args)
{
String data = "AAABBB";
SendReceive sr = new SendReceive("localhost", 5000);
String res = sr.send(data);
System.out.println("Sent: "+data);
System.out.println("Received: "+res);
}
}
结果(关键部分):
Sent: AAABBB
Received: AAABBB,AAABBB
希望它有所帮助。
修改的 1.更正了包装器刷新而不是套接字流刷新。仍然认为在关闭套接字之前冲洗流包装是一种好习惯。
P.S。我应该承认,我对这种简陋的测试服务器代码的关注感到有些惊讶,特别是与我们在SO上看到的其他脏测试相比。受宠若惊。 :)