[英]Nothing Happens When I Click Connect
注意:我已經使我的機器同時成為服務器和客戶端
這是我完整的代碼:
客戶端
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;
import java.lang.Thread;
class chatboxClient {
JFrame fr;
JPanel p;
JButton send;
JTextArea ta;
JRadioButton rb;
static chatboxServer cbS=new chatboxServer();
public Thread connectThread;
chatboxClient() {
fr=new JFrame("ChatBox_CLIENT");
p=new JPanel();
send=new JButton("send");
send.addActionListener(new ActionListener() { // action listener for send
public void actionPerformed(ActionEvent ae) {
sendActionPerformed(ae);
}
});
ta=new JTextArea();
ta.setRows(20);
ta.setColumns(20);
rb=new JRadioButton("Connect"); // action listener for connect
rb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
connectActionPerformed(ae);
}
});
fr.add(p);
p.add(ta);
p.add(rb);
p.add(send);
fr.setSize(500,500);
fr.setResizable(false);
fr.setVisible(true);
}
public void connectActionPerformed(ActionEvent ae) {
EnsureEventThread();
CreateConnectThread();
}
public void CreateConnectThread() { // Seperate Thread created for handling 'connect'
Runnable r=new Runnable() {
public void run() {
connect();
}
};
connectThread=new Thread(r,"Connect Thread");
connectThread.start();
}
public void connect() {
try {
cbS.Laccept();
rb.setEnabled(false);
JOptionPane.showMessageDialog(new JFrame()," Sockets InterConnected!");
} catch(Exception exc) {
JOptionPane.showMessageDialog(new JFrame()," Connection Error..");
}
}
public void sendActionPerformed(ActionEvent ae) {
try {
String s=ta.getText();
InetAddress address=InetAddress.getLocalHost();
DatagramSocket ds=new DatagramSocket(3000,address);
byte buffer[]=new byte[800];
buffer=s.getBytes();
Runnable rR=new Runnable() { // Seperate thread for 'Receive'
public void run() {
cbS.Receive(s);
}
};
Thread TReceive=new Thread(rR,"Receive Thread");
TReceive.start();
DatagramPacket dp=new DatagramPacket(buffer,buffer.length,address,3000);
if(true) {
ds.send(dp);
cbS.Receive(s); // call Receive method of chatboxServer class
}
catch(Exception exc) {
JOptionPane.showMessageDialog(new JFrame(),"Error sending Message");
}
}
}
public void EnsureEventThread() {
try {
if(SwingUtilities.isEventDispatchThread())
return;
} catch(Exception exc) {
System.out.println(exc);
}
}
public static void main(String args[]) {
chatboxClient cbC= new chatboxClient();
}
}
服務器端
import java.awt.*;
import java.net.*;
import javax.swing.*;
import java.awt.event.*;
class chatboxServer {
JFrame fr;
JPanel p;
JTextArea ta;
JButton send;
ServerSocket ss;
byte buffer[]=new byte[800];
chatboxServer() {
fr=new JFrame("ChatBox_SERVER");
p=new JPanel();
ta=new JTextArea();
ta.setRows(20);
ta.setColumns(20);
send=new JButton("send");
fr.add(p);
p.add(ta);
p.add(send);
fr.setVisible(true);
fr.setSize(500,500);
fr.setResizable(false);
}
public void Receive(String sm) {
try {
buffer=sm.getBytes();
InetAddress address=InetAddress.getLocalHost();
DatagramSocket ds=new DatagramSocket(3000,address);
DatagramPacket dp=new DatagramPacket(buffer,buffer.length);
ds.receive(dp);
String s=new String(dp.getData(),0,dp.getLength());
ta.setText(s);
} catch(Exception exc) {
System.out.println("Error Receiving..");
}
}
public void Laccept() {
try {
ss=new ServerSocket(3000); // First making port number 3000 on server to listen
Socket s=ss.accept();
} catch(Exception exc) {
JOptionPane.showMessageDialog(new JFrame(),"Accept Failed :3000 :Server Side");
}
}
}
問題---單擊“連接”時什么也沒發生。 問題是什么 ?
我檢查過的一件事: 程序在ss.accept()中等待; 這就是我認為Laccept()調用旁邊的語句不起作用的原因...
請注意,通過以上代碼,我的目的是將消息發送到服務器,該服務器與運行客戶端的計算機相同
請清楚說明我該怎么辦?
您首先必須確定是要使用TCP還是UDP進行連接。
TCP使用Socket和ServerSocket類,並為您提供連接,通過該連接您可以發送連續的字節流(也可以從另一個方向接收另一個字節流)。 TCP協議確保所有數據以正確的順序到達。
UDP使用DatagramSocket類,並發送單獨的程序包,該程序包可能到達或可能不到達另一端(通常它們可以到達,但不能保證,並且您無法確定自己是否未實現確認)。 如果它們到達某個主機/端口並且那里沒有進程在監聽,則它們將被簡單地丟棄。
通常,沒有必要將兩者混為一談。
您的程序在同一線程中一個接一個地使用UDP send
和receive
,這將導致接收套接字沒有機會讀取它,因為包已經被丟棄了。 您必須在發送包之前在單獨的線程中調用receive。
編輯(在您的評論后):
這就是UDP的工作方式。 沒有傳入軟件包的隊列。 ds.receive(dp);
call等待從現在開始到達的新包,而不是等待過去某個時間發送的包。 因此,此調用將永遠永久阻塞(另外在事件分發線程上,這意味着您不會獲得任何重畫或其他事件處理)。
就像在新線程中啟動connect()方法一樣,也在新線程中啟動服務器的Receive
方法。 (實際上,服務器的Laccept
不會用於任何用途。)
除此之外,您的兩個DatagramSocket(客戶端一個和服務器一個)綁定到同一本地端口,這也可能會引起問題。 不要這樣
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.