我实际上是在尝试创建一个程序:
public void setUpNetwork(){
try {
Socket sock = new Socket("localhost", 1101);
InputStreamReader read = new InputStreamReader(sock.getInputStream());
buff = new BufferedReader(read);
write = new PrintWriter(sock.getOutputStream());
System.out.println("Network Established");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这里,一旦建立了套接字连接,我就试图将用户输入的数据传递给打印流,然后在控制台中打印出数据。
我的服务器类只有这么多:
ServerSocket server = new ServerSocket(1101);
Socket socket = server.accept();
当我运行它时(在运行时,我首先运行服务器然后运行ChatSetUp类),控制台上没有任何内容被打印出来!是因为sersock.accept()给出了一个具有不同端口的套接字连接,而客户端无法与服务器通信?如果是这样,我需要将套接字对象从服务器传递到另一个类中的setUpNetwork(),以便我可以在其上创建输入流。我该怎么做?
编辑:
我已经修改了整个程序了!我正在使用Swing创建GUI,当用户在文本字段中输入文本并点击发送时,它会触发监听器,这就是我将文本添加到PrintWriter的位置。整个代码如下:....和setUpNetwork()也是这个类的一部分(不包括在下面)
编辑:在同一程序中包含服务器代码并为服务器启动新线程。
public class ChatGraphs {
JTextField field;
JTextArea area;
PrintWriter write;
BufferedReader buff;
Socket sock;
public static void main(String[] args) {
ChatGraphs grap = new ChatGraphs();
grap.doIt();
}
private void doIt() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel allPanel = new JPanel();
allPanel.setLayout(new BoxLayout(allPanel, BoxLayout.Y_AXIS));
JPanel areaPanel = new JPanel();
areaPanel.setLayout(new FlowLayout());
JLabel alabel = new JLabel("Chats");
area = new JTextArea(20, 50);
area.setEditable(false);
areaPanel.add(alabel);
areaPanel.add(area);
JPanel textPanel = new JPanel();
textPanel.setLayout(new FlowLayout());
JLabel flabel = new JLabel("Enter");
field = new JTextField(20);
JButton button = new JButton("Send");
button.addActionListener(new ButtonListen());
textPanel.add(flabel);
textPanel.add(field);
textPanel.add(button);
allPanel.add(areaPanel);
allPanel.add(textPanel);
ConnectServer con = new ConnectServer();
Thread t = new Thread(con);
t.start();
AddData add = new AddData();
Thread t1 = new Thread(add);
t1.start();
//setUpServer();
setUpClient();
frame.setSize(700,500);
frame.setVisible(true);
frame.getContentPane().add(allPanel);
}
public class ButtonListen implements ActionListener{
@Override
public void actionPerformed(ActionEvent arg0) {
write.println(field.getText());
write.flush();
field.setText("");
field.setRequestFocusEnabled(true);
}
}
private void setUpClient(){
try {
sock = new Socket("localhost", 1101);
InputStreamReader read = new InputStreamReader(sock.getInputStream());
buff = new BufferedReader(read);
System.out.println("Network Established");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public class AddData implements Runnable{
@Override
public void run() {
String line="";
try {
while((line=buff.readLine())!=null){
System.out.println("Another net");
area.append(line);
}
buff.close();
write.close();
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class ConnectServer implements Runnable{
public void run() {
ServerSocket sersock = null;
Socket sock = null;
try {
sersock = new ServerSocket(1101);
sock = sersock.accept();
write = new PrintWriter(sock.getOutputStream());
sersock.close();
sock.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
我得到的例外是:
Exception in thread "Thread-2" java.lang.NullPointerException
at org.sockets.ChatGraphs$AddData.run(ChatGraphs.java:120) // This line is : while((line=buff.readLine())!=null)
at java.lang.Thread.run(Unknown Source)
Network Established
答案 0 :(得分:4)
PrintWriter
是那些在缓冲和刷新方面表现不佳的类之一。一个简单的解决方法是使用
new PrintWriter(sock.getOutputStream(), true);
启用自动刷新。
或者,每次将数据发送给客户时,您都可以致电write.flush()
。
请注意,在关闭flush()
之前需要调用PrintWriter
一次,因为它本身不会这样做(与任何其他I / O类不同)。
答案 1 :(得分:3)
客户端和服务器如何通过套接字找到对方?
因此,将客户端连接到服务器的代码片段如下:
Socket socket4Client = new Socket("IP-Address, e.g. 123.45.67.89", PORT_NUMBER);
服务器的代码片段如下:
ServerSocket serverSocket = new ServerSocket(PORT_NUMBER);
Socket socket4Server = serverSocket.accept(); // Waits for a Client to connect
对于服务器端,您可能希望为每个传入连接启动一个新线程。查看这些Tiny Applications以获取一些非常简单(仅仅是不过分简化)的示例。
修改/添加量:强>
关于第NullPointerException
行中的新问题while(..
。
您得到异常,因为buff
为空。这是因为在调用方法ConnectServer
之前启动了线程setUpClient()
。您可以创建线程但必须在实际setUpClient()
线程之前调用start()
。