【发布时间】:2013-11-16 18:45:52
【问题描述】:
我正在开发一个连接到服务器并来回对话的程序。
服务器最初发送String,然后我发回第一封信,服务器发送第二封,我发送第三封,依此类推。
没有发送字符串最后一个字母的人发送“完成!”。
我的程序正在运行到获取字符串并分解为字符的地步,但似乎不会进入 while 循环,我不知道为什么。
下面是我的代码和我试图通过的测试用例。
有人可以解释为什么我的代码不工作(我认为它与 while 循环有关),以及我需要做些什么来修复它?
我的代码
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class Program2 {
static String rec;
public static void goClient(){
try{
String server = "localhost";
int port = 4321;
Socket socket = new Socket(server, port);
InputStream inStream = socket.getInputStream();
OutputStream outStream = socket.getOutputStream();
Scanner scan = new Scanner(inStream);
PrintWriter out = new PrintWriter(outStream);
rec = scan.nextLine();
System.out.println(rec);
char[] array = new char[rec.length()];
for(int i = 0; i < rec.length(); i++){
array[i] = rec.charAt(i);
System.out.println(array[i]);
}
if(array.length % 2 == 0){
while(scan.hasNext()){
for(int x = 0; x < array.length; x+=2){
String str;
str = Character.toString(array[x]);
System.out.print(str);
out.println(str);
str = scan.nextLine();
System.out.print(str);
}
}
}
if(array.length % 2 != 0){
while(scan.hasNext()){
for(int x = 0; x < array.length - 1; x+=2){
String str;
str = Character.toString(array[x]);
System.out.print(str);
out.println(str);
str = scan.nextLine();
System.out.print(str);
}
}
out.println("done!");
}
scan.close();
socket.close();
} catch (IOException e) {}
}
}
Junit 测试用例
import static org.junit.Assert.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;
import org.junit.Before;
import org.junit.Test;
public class Program2Test {
@Before
public void wait2SecondsBeforeEachTest() {
try {
Thread.sleep( 2000 );
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
@Test
public void test0() {
Runnable client = new Runnable() {
@Override
public void run() {
Program2.goClient();
}
};
final CountDownLatch gate = new CountDownLatch( 1 );
Runnable server = new Runnable() {
@Override
public void run() {
ServerSocket server = null;
try {
server = new ServerSocket( 4321 );
Socket client = server.accept();
PrintWriter out = new PrintWriter( client.getOutputStream(), true );
Scanner in = new Scanner ( client.getInputStream() );
out.println( "Lorem" );
String actual = in.nextLine();
assertEquals( "Incorrect result", "L", actual );
out.println( "o" );
actual = in.nextLine();
assertEquals( "Incorrect result", "r", actual );
out.println( "e" );
actual = in.nextLine();
assertEquals( "Incorrect result", "m", actual );
out.println( "done!" );
assertFalse( "Client hasn't closed its socket", in.hasNext() );
client.close();
gate.countDown();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
if (server != null) {
server.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
};
Thread serverThread = new Thread( server );
serverThread.start();
Thread clientThread = new Thread( client );
clientThread.start();
int count = 0;
while (serverThread.isAlive() && count++ < 300) {
try {
Thread.sleep( 10 );
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
assertTrue( "Client did not arrive or did not finish correctly", gate.getCount() == 0 );
}
@Test
public void test1() {
Runnable client = new Runnable() {
@Override
public void run() {
Program2.goClient();
}
};
final CountDownLatch gate = new CountDownLatch( 1 );
Runnable server = new Runnable() {
@Override
public void run() {
ServerSocket server = null;
try {
server = new ServerSocket( 4321 );
Socket client = server.accept();
PrintWriter out = new PrintWriter( client.getOutputStream(), true );
Scanner in = new Scanner ( client.getInputStream() );
out.println( "Let it be." );
String actual = in.nextLine();
assertEquals( "Incorrect result", "L", actual );
out.println( "e" );
actual = in.nextLine();
assertEquals( "Incorrect result", "t", actual );
out.println( " " );
actual = in.nextLine();
assertEquals( "Incorrect result", "i", actual );
out.println( "t" );
actual = in.nextLine();
assertEquals( "Incorrect result", " ", actual );
out.println( "b" );
actual = in.nextLine();
assertEquals( "Incorrect result", "e", actual );
out.println( "." );
actual = in.nextLine();
assertEquals( "Incorrect result", "done!", actual );
assertFalse( "Client hasn't closed its socket", in.hasNext() );
client.close();
gate.countDown();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
if (server != null) {
server.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
};
Thread serverThread = new Thread( server );
serverThread.start();
Thread clientThread = new Thread( client );
clientThread.start();
int count = 0;
while (serverThread.isAlive() && count++ < 300) {
try {
Thread.sleep( 10 );
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
assertTrue( "Client did not arrive or did not finish correctly", gate.getCount() == 0 );
}
@Test
public void test2() {
Runnable client = new Runnable() {
@Override
public void run() {
Program2.goClient();
}
};
final CountDownLatch gate = new CountDownLatch( 1 );
Runnable server = new Runnable() {
@Override
public void run() {
ServerSocket server = null;
try {
server = new ServerSocket( 4321 );
Socket client = server.accept();
PrintWriter out = new PrintWriter( client.getOutputStream(), true );
Scanner in = new Scanner ( client.getInputStream() );
out.println( "Upside Down" );
String actual = in.nextLine();
assertEquals( "Incorrect result", "U", actual );
out.println( "p" );
actual = in.nextLine();
assertEquals( "Incorrect result", "s", actual );
out.println( "i" );
actual = in.nextLine();
assertEquals( "Incorrect result", "d", actual );
out.println( "e" );
actual = in.nextLine();
assertEquals( "Incorrect result", " ", actual );
out.println( "D" );
actual = in.nextLine();
assertEquals( "Incorrect result", "o", actual );
out.println( "w" );
actual = in.nextLine();
assertEquals( "Incorrect result", "n", actual );
out.println( "done!" );
assertFalse( "Client hasn't closed its socket", in.hasNext() );
client.close();
gate.countDown();
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
if (server != null) {
server.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
};
Thread serverThread = new Thread( server );
serverThread.start();
Thread clientThread = new Thread( client );
clientThread.start();
int count = 0;
while (serverThread.isAlive() && count++ < 300) {
try {
Thread.sleep( 10 );
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
assertTrue( "Client did not arrive or did not finish correctly", gate.getCount() == 0 );
}
}
控制台输出
Lorem
L
o
r
e
m
java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
at java.net.AbstractPlainSocketImpl.bind(Unknown Source)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at Program2Test$4.run(Program2Test.java:112)
at java.lang.Thread.run(Unknown Source)
java.net.BindException: Address already in use: JVM_Bind
at java.net.DualStackPlainSocketImpl.bind0(Native Method)
at java.net.DualStackPlainSocketImpl.socketBind(Unknown Source)
at java.net.AbstractPlainSocketImpl.bind(Unknown Source)
at java.net.PlainSocketImpl.bind(Unknown Source)
at java.net.ServerSocket.bind(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at java.net.ServerSocket.<init>(Unknown Source)
at Program2Test$6.run(Program2Test.java:199)
at java.lang.Thread.run(Unknown Source)
【问题讨论】:
-
catch (IOException e) {}是个坏主意。以某种方式处理它,即使它只是打印堆栈跟踪。这可能会让您对正在发生的事情有所了解。 -
添加了堆栈跟踪的打印,似乎我没有收到 IO 异常。我将打印语句的输出添加到控制台。它似乎正在通过将字符放入数组然后失败,这让我认为这是某种while循环错误,导致第一个测试失败并且不关闭套接字女巫导致其他测试失败并给出 JVN 错误。
标签: java sockets loops io client-server