[英]Server and Client using Sockets
是否有使用套接字但具有send和get方法的服务器和客户端的任何示例? 我正在做这个联网的战列舰程序,快要完成了,但是无法使服务器和客户端正常工作。 我制作了一个仅发送字符串的聊天程序,但是这次我需要发送对象。 我已经很沮丧,所以是否有任何源代码已经有了这个。
这是客户端的代码...您将如何对其进行修改以允许发送对象? 另外,我还需要监听传入的对象并立即对其进行处理。
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SimpleChat extends JFrame {
private Socket communicationSocket = null;
private PrintWriter outStream = null;
private BufferedReader inStream = null;
private Boolean communicationContinue = true;
private String disconnectString = "disconnect764*#$1";
private JMenuItem disconnectItem;
private JTextField displayLabel;
private final Color colorValues[] = { Color.black, Color.blue, Color.red, Color.green };
// set up GUI
public SimpleChat() {
super("Simple Chat");
// set up File menu and its menu items
JMenu fileMenu = new JMenu("File");
fileMenu.setMnemonic('F');
// set up Activate Server menu item
JMenuItem serverItem = new JMenuItem("Activate Server");
serverItem.setMnemonic('S');
fileMenu.add(serverItem);
serverItem.addActionListener(new ActionListener() { // anonymous inner class
// display message dialog when user selects About...
public void actionPerformed(ActionEvent event) {
setUpServer();
}
} // end anonymous inner class
); // end call to addActionListener
// set up Activate Client menu item
JMenuItem clientItem = new JMenuItem("Activate Client");
clientItem.setMnemonic('C');
fileMenu.add(clientItem);
clientItem.addActionListener(new ActionListener() { // anonymous inner class
// display message dialog when user selects About...
public void actionPerformed(ActionEvent event) {
setUpClient();
}
} // end anonymous inner class
); // end call to addActionListener
// set up Activate Client menu item
disconnectItem = new JMenuItem("Disconnect Client/Server");
disconnectItem.setMnemonic('D');
disconnectItem.setEnabled(false);
fileMenu.add(disconnectItem);
disconnectItem.addActionListener(new ActionListener() { // anonymous inner
// class
// display message dialog when user selects About...
public void actionPerformed(ActionEvent event) {
disconnectClientServer(true);
}
} // end anonymous inner class
); // end call to addActionListener
// set up About... menu item
JMenuItem aboutItem = new JMenuItem("About...");
aboutItem.setMnemonic('A');
fileMenu.add(aboutItem);
aboutItem.addActionListener(new ActionListener() { // anonymous inner class
// display message dialog when user selects About...
public void actionPerformed(ActionEvent event) {
JOptionPane.showMessageDialog(SimpleChat.this, "This is an example\nof using menus", "About",
JOptionPane.PLAIN_MESSAGE);
}
} // end anonymous inner class
); // end call to addActionListener
// set up Exit menu item
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.setMnemonic('x');
fileMenu.add(exitItem);
exitItem.addActionListener(new ActionListener() { // anonymous inner class
// terminate application when user clicks exitItem
public void actionPerformed(ActionEvent event) {
disconnectClientServer(true);
System.exit(0);
}
} // end anonymous inner class
); // end call to addActionListener
// create menu bar and attach it to MenuTest window
JMenuBar bar = new JMenuBar();
setJMenuBar(bar);
bar.add(fileMenu);
// set up label to display text
displayLabel = new JTextField("Sample Text", SwingConstants.CENTER);
displayLabel.setForeground(colorValues[0]);
displayLabel.setFont(new Font("Serif", Font.PLAIN, 72));
displayLabel.addActionListener(new ActionListener() { // anonymous inner
// class
// display message dialog when user selects About...
public void actionPerformed(ActionEvent event) {
sendData();
}
} // end anonymous inner class
); // end call to addActionListener
getContentPane().setBackground(Color.CYAN);
getContentPane().add(displayLabel, BorderLayout.CENTER);
setSize(500, 200);
setVisible(true);
} // end constructor
public static void main(String args[]) {
final SimpleChat application = new SimpleChat();
application.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
application.disconnectClientServer(true);
System.exit(0);
}
});
// application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
public void setCommunicationSocket(Socket sock) {
communicationSocket = sock;
communicationContinue = true;
disconnectItem.setEnabled(true);
}
public void setOutStream(PrintWriter out) {
outStream = out;
}
public void setInStream(BufferedReader in) {
inStream = in;
}
public void setUpServer() {
ServerThread st = new ServerThread(this);
st.start();
}
public void setUpClient() {
ClientThread st = new ClientThread(this);
st.start();
}
public void disconnectClientServer(Boolean sendMessage) {
if (communicationSocket == null)
return;
try {
// shut down socket read loop
communicationContinue = false;
disconnectItem.setEnabled(false);
// send notification to other end of socket
if (sendMessage == true)
outStream.println(disconnectString);
// sleep to let read loop shut down
Thread t = Thread.currentThread();
try {
t.sleep(500);
} catch (InterruptedException ie) {
return;
}
outStream.close();
inStream.close();
communicationSocket.close();
} catch (IOException e) {
System.err.println("Stream Read Failed.");
JOptionPane.showMessageDialog(SimpleChat.this, "Disconnection Failed", "SimpleChat", JOptionPane.PLAIN_MESSAGE);
return;
} finally {
communicationSocket = null;
}
}
public void sendData() {
if (communicationSocket != null) {
String data = displayLabel.getText();
outStream.println(data);
}
}
public void getData() {
String inputLine;
try {
while (communicationContinue == true) {
communicationSocket.setSoTimeout(100);
// System.out.println ("Waiting for Connection");
try {
while (((inputLine = inStream.readLine()) != null)) {
System.out.println("From socket: " + inputLine);
if (inputLine.equals(disconnectString)) {
disconnectClientServer(false);
return;
}
displayLabel.setText(inputLine);
}
} catch (SocketTimeoutException ste) {
// System.out.println ("Timeout Occurred");
}
} // end of while loop
System.out.println("communication is false");
} catch (IOException e) {
System.err.println("Stream Read Failed.");
JOptionPane.showMessageDialog(SimpleChat.this, "Input Stream read failed", "SimpleChat",
JOptionPane.PLAIN_MESSAGE);
return;
}
}
}
class ServerThread extends Thread {
private SimpleChat sc;
private JTextField display;
public ServerThread(SimpleChat scParam) {
sc = scParam;
}
public void run() {
ServerSocket connectionSocket = null;
try {
connectionSocket = new ServerSocket(10007);
} catch (IOException e) {
System.err.println("Could not listen on port: 10007.");
JOptionPane.showMessageDialog(sc, "Could not listen on port: 10007", "Server", JOptionPane.PLAIN_MESSAGE);
return;
}
JOptionPane.showMessageDialog(sc, "Server Socket is now activated", "Server", JOptionPane.PLAIN_MESSAGE);
Socket communicationSocket = null;
try {
communicationSocket = connectionSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
JOptionPane.showMessageDialog(sc, "Accept failed", "Server", JOptionPane.PLAIN_MESSAGE);
return;
}
JOptionPane.showMessageDialog(sc, "Comminucation is now activated", "Server", JOptionPane.PLAIN_MESSAGE);
try {
PrintWriter out = new PrintWriter(communicationSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(communicationSocket.getInputStream()));
sc.setCommunicationSocket(communicationSocket);
sc.setOutStream(out);
sc.setInStream(in);
connectionSocket.close();
sc.getData();
} catch (IOException e) {
System.err.println("Accept failed.");
JOptionPane.showMessageDialog(sc, "Creation of Input//Output Streams failed", "Server", JOptionPane.PLAIN_MESSAGE);
return;
}
}
}
class ClientThread extends Thread {
private SimpleChat sc;
public ClientThread(SimpleChat scParam) {
sc = scParam;
}
public void run() {
Socket echoSocket = null;
PrintWriter out = null;
BufferedReader in = null;
String ipAddress = "127.0.0.1";
try {
echoSocket = new Socket(ipAddress, 10007);
out = new PrintWriter(echoSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + ipAddress);
JOptionPane.showMessageDialog(sc, "Don't know about host: " + ipAddress, "Client", JOptionPane.PLAIN_MESSAGE);
return;
} catch (IOException e) {
System.err.println("Couldn't get I/O for " + "the connection to: " + ipAddress);
JOptionPane.showMessageDialog(sc, "Couldn't get I/O for the connection to: " + ipAddress, "Client",
JOptionPane.PLAIN_MESSAGE);
return;
}
JOptionPane.showMessageDialog(sc, "Comminucation is now activated", "Client", JOptionPane.PLAIN_MESSAGE);
sc.setCommunicationSocket(echoSocket);
sc.setOutStream(out);
sc.setInStream(in);
sc.getData();
}
}
我建议您阅读Java序列化。 有一个例子在这里 。 基本上,内置了序列化支持。 您的课程需要实现Serializable 。 然后,使用ObjectOutputStream和ObjectInputStream编写对象。
强烈建议您使用使您免于容易出错的低级套接字编程的库。
对于C ++,请看Boost( http://www.boost.com )或ACE( http://www.cs.wustl.edu/~schmidt/ACE.html )
对于Java,我只找到了一个有关接受者模式的文档, 网址为http://www.hillside.net/plop/plop99/proceedings/Fernandez3/RACPattern.PDF,但是我确定某个地方有实现
您走对了。 聊天程序是开始学习套接字的好地方。
您要使用ObjectOutputStream和ObjectInputStream类。 您只需要用这些过滤器包装您的输入流/输出流。 ObjectOutputStream具有方法writeObject(),而ObjectInputStream具有对应的readObject()方法。
大多数序列化示例都显示了将对象读取和写入文件的过程,但是可以使用套接字流来完成相同的操作。 参见http://www.acm.org/crossroads/xrds4-2/serial.html
我不花时间阅读大量的代码,但是总的来说,您不能直接通过网络发送对象。 网络通信只是位和字节。 如果要发送对象,则需要在发送端对它们进行序列化,然后在接收端对它们进行反序列化。 有大量的序列化方法,例如JSON,XML甚至Java的内置序列化支持(仅当客户端和服务器始终都是Java时才建议使用)。
您可能会发现此代码是制作自己的类的一个不错的起点。 我制作了两个类,以稍微抽象化TCP和UDP套接字协议所需的工作:
http://code.google.com/p/hivewars/source/browse/trunk/SocketData.java http://code.google.com/p/hivewars/source/browse/trunk/UDPSocket.java
快速免责声明:这些是全功能类的一种版本,我只是在需要时添加了功能。 但是,它可以帮助您开始。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.