嗨,我希望你们做得很好。
我目前正在尝试测试一个创建与打印服务器的套接字连接的服务类。
这是服务类:
public class PrintServiceImpl implements PrintService {
private static final Logger LOGGER = LoggerFactory.getLogger(PrintServiceImpl.class);
static final int TIMEOUT_MILLISECOND = 20000;
@Override
public boolean sendLabelToPrintServer(String hostname, int port, String labelData) {
Socket clientSocket = null;
DataOutputStream outToServer = null;
Boolean successful;
try {
// open the connection to the printing server
clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(hostname, port), TIMEOUT_MILLISECOND);
clientSocket.setSoTimeout(TIMEOUT_MILLISECOND);
outToServer = new DataOutputStream(clientSocket.getOutputStream());
// send data to print
outToServer.writeBytes(labelData);
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream(),
StandardCharsets.UTF_8));
// Read HTTP Request CHARACTER BY CHARACTER instead of line by line
while ((char) input.read() != 0 && (char) input.read() != '\r') {
LOGGER.debug("Getting print server answer.");
}
successful = true;
LOGGER.debug("Label printed.");
} catch (Exception e) {
LOGGER.error("Printing failed.", e);
successful = false;
} finally {
try {
// close connection
if (outToServer != null) {
outToServer.close();
}
if (clientSocket != null) {
clientSocket.close();
}
} catch (IOException e) {
LOGGER.error("Exception while closing DataOutputStream/ClientSocket.", e);
}
}
return successful;
}
这是我的考试班。如您所见,@ Before方法在新线程上实例化SocketServer。
public class PrintServiceImplTest {
private static final Logger LOGGER = LoggerFactory.getLogger(PrintServiceImplTest.class);
PrintServiceImpl whfPrintService = new PrintServiceImpl();
private static final String LOCALHOST = "localhost";
private static final int SERVER_PORT = 3000;
private static final String LABEL_TEXT = "This dummy text is sent to the print server";
private static final String RESPONSE = "Test Label printed correctly";
private ServerSocket server;
private Socket incommingSocket = null;
@Before
public void before() {
Thread myThread = new Thread() {
@Override
public void run() {
try {
server = new ServerSocket(SERVER_PORT);
incommingSocket = server.accept();
} catch (IOException e) {
e.printStackTrace();
}
}
};
myThread.start();
}
@After
public void after() {
try {
incommingSocket.close();
server.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void returnsTrueIfConnectionSuccessful() {
BufferedReader reader = null;
PrintWriter out = null;
BufferedReader in = null;
String line;
whfPrintService.sendLabelToPrintServer(LOCALHOST, SERVER_PORT, LABEL_TEXT);
try {
in = new BufferedReader(new InputStreamReader(incommingSocket.getInputStream()));
out = new PrintWriter(incommingSocket.getOutputStream());
reader = new BufferedReader(new InputStreamReader(incommingSocket.getInputStream()));
while ((line = reader.readLine()) != null) {
System.out.println("line : " + line);
}
out.write(RESPONSE);
out.flush();
out.close();
in.close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
当我运行测试时,我得到一个SocketTimoutException。它发生在客户端从服务器读取响应时。这一行:
while ((char) input.read() != 0 && (char) input.read() != '\r') {
所以这意味着客户端没有收到回复。我的猜测是服务器没有发送正确的响应。
我错过了什么?提前谢谢你。
答案 0 :(得分:0)
您的回复不会以\0
或\r
结尾。
private static final String RESPONSE = "Test Label printed correctly";
通过使用这些字符中的任何一个来结束响应,客户端将从循环中退出。
private static final String RESPONSE = "Test Label printed correctly\0";
客户端使用以下代码读取响应:
while ((char) input.read() != 0 && (char) input.read() != '\r') {
每次调用input.read()
都会从网络返回一个新字节。你应该每次循环调用input.read()
一次,并在之后进行比较。
char c;
while (c = (char) input.read()) != -1) {
if(c == 0 || c == '\r') {
break;
}
}
从客户端发送到服务器的消息没有结束,服务器会一直读取,直到套接字输入关闭,但客户端永远不会关闭套接字。
// send data to print outToServer.writeBytes(labelData);
写完这些字节后,请拨打socket.shutdownOutput()
向另一方发出文件结束信号。
// send data to print
outToServer.writeBytes(labelData);
clientSocket.shutdownOutput();