我正在为学习经验而进行的客户端/服务器聊天的客户端应用程序上工作。我的问题是我似乎无法同时运行套接字和摆动。
我想要的是,当用户打开一个JOpionsPane并输入主机名和端口号时,单击“确定”,然后将它们连接起来。当套接字信息被硬编码时,它可以正常工作,但是现在我正试图让用户输入它。
这意味着要发生的事情是, Action 监听器应该创建用于处理通信的新SocketManager对象。事件,尽管它表示已连接,但未运行。当我创建新的SocketManager对象并在新线程上运行它时,它将连接并恢复服务器中的消息,但是随后的 Action 停止了,我必须结束将其关闭的过程。
我应该在新的工作线程上启动它吗?也许只是因为我累了,但我没有主意。
编辑
我更新了ActLis.class和SocketManager.class,并建议为SocketManager对象“网络”添加新线程。当我尝试使用“网络”时,尽管出于某种原因它返回null。
ActLis.clss
package com.client.core;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class ActLis implements ActionListener {
private Main main = new Main();;
private JTextField ipadress = new JTextField(),
portnumber = new JTextField(),
actionField;
private String username;
final JComponent[] ipinp = new JComponent[]{new JLabel("Enter Hostname (IP Adress): "),
ipadress,
new JLabel("Enter Port number: "), portnumber};
private SocketManager network;
private Window win;
public ActLis(){
}
public ActLis(JTextField t, Window w){
actionField = t;
win = w;
}
@Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if(cmd == "Exit"){
System.exit(0);
} else if(cmd == "Connect to IP"){
try{
JOptionPane.showMessageDialog(null, ipinp, "Connect to IP", JOptionPane.PLAIN_MESSAGE);
if(network != null){
network.close();
}
network = new SocketManager(ipadress.getText(),Integer.parseInt(portnumber.getText()));
network.setGUI(win);
Thread t = new Thread(network);
t.start();
JOptionPane.showMessageDialog(null, "Connected to chat host successfully!","Connected", JOptionPane.INFORMATION_MESSAGE);
}catch(Exception ee){
JOptionPane.showMessageDialog(null, "Could not connect. Check IP adress or internet connection","Error - Could not connect", JOptionPane.ERROR_MESSAGE);
ee.printStackTrace();
}
} else if (cmd == "chatWriter"){
if( actionField.getText() != ""){
try{
network.send(actionField.getText());
win.updateChat(actionField.getText());
actionField.setText("");
actionField.requestFocus();
}catch(Exception ex){
JOptionPane.showMessageDialog(null, "You are not connected to a host. (File -> Connect to IP)","Error - Not Connected", JOptionPane.ERROR_MESSAGE);
ex.printStackTrace();
}
}
} else if (cmd == "setUsername"){
username = actionField.getText();
network.send("USERNAME:" + username);
}
}
}
主类
package com.client.core;
import javax.swing.JFrame;
public class Main extends JFrame{
private SocketManager network;
public static void main(String[] args){
Main main = new Main();
main.run();
}
private void run(){
Window win = new Window();
win.setVisible(true);
}
}
SocketManager.class
package com.client.core;
import java.io.*;
import java.net.*;
public class SocketManager implements Runnable {
private Socket sock;
private PrintWriter output;
private BufferedReader input;
private String hostname;
private int portnumber;
private String message;
private Window gui;
public SocketManager(String ip, int port){
try{
hostname = ip;
portnumber = port;
}catch(Exception e){
System.out.println("Client: Socket failed to connect.");
}
}
public synchronized void send(String data){
try{
//System.out.println("Attempting to send: " + data);
output.println(data);
output.flush();
//System.out.println("Message sent.");
}catch(Exception e){
System.out.println("Message could not send.");
}
}
public synchronized void setGUI(Window w){
gui = w;
}
public synchronized void connect(){
try{
sock = new Socket(hostname,portnumber);
}catch(Exception e){
}
}
public synchronized Socket getSocket(){
return sock;
}
public synchronized void setSocket(SocketManager s){
sock = s.getSocket();
}
public synchronized void close(){
try{
sock.close();
}catch(Exception e){
System.out.println("Could not close connection.");
}
output = null;
input = null;
System.gc();
}
public synchronized boolean isConnected(){
return (sock == null) ? false : (sock.isConnected() && !sock.isClosed());
}
public synchronized void listenStream(){
try {
while((message = input.readLine()) != null){
System.out.println("Server: " + message);
gui.updateChat(message);
}
} catch (Exception e) {
}
}
@Override
public void run() {
try {
sock = new Socket(hostname,portnumber);
output = new PrintWriter(sock.getOutputStream(),true);
input = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
while(true){
listenStream();
}
} catch (Exception e) {
System.out.println("Run method fail. -> SocketManager.run()");
}finally{
try {
sock.close();
} catch (Exception e) {
}
}
}
}
Window.class
package com.client.core;
import java.awt.*;
import javax.swing.*;
public class Window extends JFrame{
private int screenWidth = 800;
private int screenHeight = 600;
private SocketManager network;
private JPanel window = new JPanel(new BorderLayout()),
center = new JPanel(new BorderLayout()),
right = new JPanel(new BorderLayout()),
display = new JPanel( new BorderLayout()),
chat = new JPanel(),
users = new JPanel(new BorderLayout());
private JTextArea chatBox = new JTextArea("Welcome to the chat!", 7,50),
listOfUsers = new JTextArea("None Online");
private JTextField chatWrite = new JTextField(),
userSearch = new JTextField(10),
username = new JTextField();
private JScrollPane userList = new JScrollPane(listOfUsers),
currentChat = new JScrollPane(chatBox);
private JMenuBar menu = new JMenuBar();
private JMenu file = new JMenu("File");
private JMenuItem exit = new JMenuItem("Exit"),
ipconnect = new JMenuItem("Connect to IP");
private JComponent[] login = new JComponent[]{new JLabel("Username:"), username};
public Window(){
//Initial Setup
super("NAMEHERE - Chat Client Alpha v0.0.1");
setResizable(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(screenWidth,screenHeight);
//Panels
listOfUsers.setLineWrap(true);
listOfUsers.setEditable(false);
display.setBackground(Color.black);
chat.setLayout(new BoxLayout(chat, BoxLayout.Y_AXIS));
chat.setBackground(Color.blue);
users.setBackground(Color.green);
//TextFields
addChatArea();
//Menu bar
addMenuBar();
//Adding the main panels.
addPanels();
//Listeners
addListeners();
for(int x = 0; x < 1; x++){
login();
}
}
private void login(){
JOptionPane.showMessageDialog(null, login, "Log in", JOptionPane.PLAIN_MESSAGE);
}
private void addChatArea(){
chatBox.setEditable(false);
userList.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
currentChat.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
users.add(userList);
users.add(userSearch, BorderLayout.NORTH);
chat.add(currentChat);
chat.add(chatWrite);
chat.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
}
private void addMenuBar(){
file.add(ipconnect);
file.add(exit);
menu.add(file);
}
private void addPanels(){
right.add(users);
center.add(display, BorderLayout.CENTER);
center.add(chat, BorderLayout.SOUTH);
window.add(center, BorderLayout.CENTER);
window.add(right, BorderLayout.EAST);
window.add(menu, BorderLayout.NORTH);
add(window);
}
private void addListeners(){
username.addActionListener(new ActLis(username, this));
chatWrite.addActionListener(new ActLis(chatWrite, this));
username.setActionCommand("setUsername");
chatWrite.setActionCommand("chatWriter");
ipconnect.addActionListener(new ActLis());
exit.addActionListener(new ActLis());
}
public void setNetwork(SocketManager n){
network = n;
}
public void updateChat(String s){
chatBox.setText(chatBox.getText() + "\n" + s);
}
}
最佳答案
好了@Zexanima,您已经为套接字管理器创建了一个Socket类。像这样的东西:
public class YouSocketClass {
static public Socket socket = null;
static public InputStream in = null;
static public OutputStream out = null;
public YouSocketClass() {
super();
}
public static final Socket getConnection(final String ip, final int port, final int timeout) {
try {
socket = new Socket(ip, port);
try {
socket.setSoTimeout(timeout);
} catch(SocketException se) {
log("Server Timeout");
}
in = socket.getInputStream();
out = socket.getOutputStream();
} catch(ConnectException e) {
log("Server name or server ip is failed. " + e.getMessage());
e.printStackTrace();
} catch(Exception e) {
log("ERROR Socket: " + e.getMessage() + " " + e.getCause());
e.printStackTrace();
}
return socket;
}
public static void closeConnection() {
try {
if(socket != null) {
if(in != null) {
if(out != null) {
socket.close();
in.close();
out.close();
}
}
}
} catch(Exception e2) {
e2.printStackTrace();
}
}
private static Object log(Object sms) {
System.out.println("Test Socket1.0: " + sms);
return sms;
}
}
希望能为您服务。 :)