java socket 编程实现网络交谈和同步操作
目标
用java socket编程和多线程机制实现网络交谈和同步操作。
1、程序网络结构图
2、流程图
3、原理
①Java Swing编程
该网络交谈小程序使用了Java Swing编程技术,实现画图、编辑消息等功能;
②多线程
该程序使用了多线程技术,在程序运行过程中产生了多个线程。在创建客户端时,为每个客户端开启一个线程,这样客户端之间可以看成是相互独立的。
③Socket编程
该程序使用了socket编程技术,主进程(即服务器)创建一个服务器端的socket,指定绑定的端口,并监听该端口。当有客户端socket向该端口发送消息时,服务器端接收消息并将该客户端放入一个队列中,该队列中存放当前访问该端口的所有客户端。当服务器向客户端发送消息时,遍历该队列中的所有客户端,同时向所有客户端发送消息。当客户端有消息发送到服务器时,服务器接收该消息,并将该消息转发给客户端队列中的所有客户端,实现消息共享。 注意: ConnectionException : 对于客户进程, 如果它发出的连接请求被加入到服务器的请求连接队列中, 就意味着客户与服务器的连接建立成功, 客户进程从 Socket 构造方法中正常返回. 如果客户进程发出的连接请求被服务器拒绝, Socket 构造方法就会抛出 ConnectionException. 必须在服务器进程通过 ServerSocket 的 accept() 方法从请求连接队列中取出连接请求, 并返回一个Socket 对象后, 服务器进程这个Socket 对象才与客户端的 Socket 对象形成一条通信线路. 相关博客:http://blog.csdn.net/qq_23473123/article/details/51461894
4、程序的输入与输出
输入:在“画图”窗口中绘图,在“聊天”窗口中发送消息。 输出:服务器和各客户端同步共享窗口内容。
5、程序运行截图
a. 如下图所示,运行程序,可看到名为“ycc的通信小程序”的窗口,该窗口包含一个下拉框,一个画图面板和一个聊天面板;
b. 如下图所示,点击下拉框上的“文件”按钮,弹出“添加客户端”按钮,单击该按钮可添加客户端;
c. 如下图所示,这里添加了三个客户端,在服务器或任意客户端上画图,其它窗口可同步显示该图片;
d. 如下图所示,点击“聊天”面板,在服务器或任意客户端窗口的编辑框中编辑消息并点击发送按钮,其它窗口均可显示该消息;
6、代码实现
①程序结构
②客户端Client.java
package networkTalk;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import networkTalk.Client;
public class Client extends JFrame{
public JTextArea area;
JTextField field;
JButton button;
public PrintWriter writer;
public Graphics g;
public JPanel contentPanel1;
public Client() {
this.setTitle(
"客户端");
this.setSize(
500,
500);
JMenu jMenu =
new JMenu(
"文件");
JMenuItem t =
new JMenuItem(
"添加客户端");
jMenu.add(t);
JMenuBar jMenuBar =
new JMenuBar();
jMenuBar.add(jMenu);
this.setJMenuBar(jMenuBar);
JTabbedPane jTabbedPane =
new JTabbedPane(JTabbedPane.LEFT);
contentPanel1 =
new JPanel();
JPanel contentPanel2 =
new JPanel();
jTabbedPane.add(
"画图",contentPanel1);
jTabbedPane.add(
"聊天",contentPanel2);
this.add(jTabbedPane,BorderLayout.CENTER);
area=
new JTextArea(
20,
30);
field =
new JTextField(
20);
button=
new JButton(
"提交");
JScrollPane sp =
new JScrollPane(area);
contentPanel2.add(sp,BorderLayout.CENTER);
contentPanel2.add(field);
contentPanel2.add(button);
this.setVisible(
true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.addActionListener(
new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
String text = field.getText();
writer.println(text);
area.append(
"我:"+text+
"\n");
field.setText(
"");
}
});
t.addActionListener(
new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
Runnable myRunnable =
new Runnable(){
@Override
public void run() {
try {
Client.main();
}
catch (Exception e) {
e.printStackTrace();
}
}
};
Thread thread =
new Thread(myRunnable);
thread.start();
}
});
contentPanel1.addMouseMotionListener(
new MouseMotionListener() {
int x=
0;
int y=
0;
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
writer.println(x +
"*" + y);
g = contentPanel1.getGraphics();
g.fillOval(x, y,
1,
1);
}
});
}
public static void main()
throws Exception{
Client c =
new Client();
Socket socket =
new Socket(
"127.0.0.1",
9995);
OutputStream out = socket.getOutputStream();
c.writer=
new PrintWriter(out,
true);
System.out.println(
"成功连接服务器!");
BufferedReader reader=
new BufferedReader(
new InputStreamReader(socket.getInputStream()));
while(
true){
String line = reader.readLine();
String a[] =
new String[
2];
a = line.split(
"\\*");
if(a.length ==
1){
c.area.append(
"客户端:"+a[
0]+
"\n");
}
else {
int x = Integer.parseInt(a[
0]);
int y = Integer.parseInt(a[
1]);
c.g = c.contentPanel1.getGraphics();
c.g.fillOval(x, y,
1,
1);
}
}
}
}
①服务器端Server.java
package networkTalk;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import networkTalk.Server;
public class Server extends JFrame{
static JTextArea area;
JTextField field;
JButton button;
static PrintStream writer;
static Graphics g;
static JPanel contentPanel1;
static ArrayList<Socket> sList;
public Server(){
this.setTitle(
"ycc的通信小程序");
this.setSize(
500,
500);
JMenu jMenu =
new JMenu(
"文件");
JMenuItem t =
new JMenuItem(
"添加客户端");
jMenu.add(t);
JMenuBar jMenuBar =
new JMenuBar();
jMenuBar.add(jMenu);
this.setJMenuBar(jMenuBar);
JTabbedPane jTabbedPane =
new JTabbedPane(JTabbedPane.LEFT);
contentPanel1 =
new JPanel();
JPanel contentPanel2 =
new JPanel();
jTabbedPane.add(
"画图",contentPanel1);
jTabbedPane.add(
"聊天",contentPanel2);
this.add(jTabbedPane,BorderLayout.CENTER);
area =
new JTextArea(
20,
30);
area.setEditable(
false);
field =
new JTextField(
20);
button =
new JButton(
"提交");
JScrollPane sp =
new JScrollPane(area);
contentPanel2.add(sp,BorderLayout.CENTER);
contentPanel2.add(field);
contentPanel2.add(button);
this.setVisible(
true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPanel1.addMouseMotionListener(
new MouseMotionListener() {
int x=
0;
int y=
0;
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
for (Socket s : sList) {
try {
PrintStream writer1;
writer1 =
new PrintStream(s.getOutputStream(),
true);
writer1.println(x +
"*" + y);
}
catch (IOException e1) {
e1.printStackTrace();
}
}
g = contentPanel1.getGraphics();
g.fillOval(x, y,
1,
1);
}
});
t.addActionListener(
new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
Runnable myRunnable =
new Runnable(){
@Override
public void run() {
try {
Client.main();
}
catch (Exception e) {
e.printStackTrace();
}
}
};
Thread thread =
new Thread(myRunnable);
thread.start();
}
});
button.addActionListener(
new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String text =field.getText();
for (Socket s : sList) {
try {
System.out.println(s);
PrintStream writer1;
writer1 =
new PrintStream(s.getOutputStream(),
true);
writer1.println(text);
}
catch (IOException e1) {
e1.printStackTrace();
}
}
area.append(
"我:"+text+
"\n");
field.setText(
"");
}
});
}
public static void main(String[] args)
throws Exception{
Server s =
new Server();
ServerSocket server =
new ServerSocket(
9995);
System.out.println(
"服务端准备完毕!开始监听请求!");
Server.sList =
new ArrayList<Socket>();
for(;;)
{
Socket socket = server.accept();
sList.add(socket);
class MyThread implements Runnable
{
private Socket m_Socket;
public void setSocket(Socket s)
{
m_Socket = s;
}
@Override
public void run() {
try {
InetAddress address =m_Socket.getInetAddress();
String name = address.getLocalHost().getHostName();
System.out.println(name+
"已成功连接");
writer=
new PrintStream(m_Socket.getOutputStream(),
true);
BufferedReader reader =
new BufferedReader(
new InputStreamReader(m_Socket.getInputStream()));
while(
true){
String line=
null;
line=reader.readLine();
String a[] =
new String[
2];
a = line.split(
"\\*");
for (Socket s : sList) {
System.out.println(s);
if (m_Socket != s) {
PrintStream writer1;
writer1 =
new PrintStream(s.getOutputStream(),
true);
writer1.println(line);
}
}
if(a.length ==
1){
area.append(
"客户端:"+a[
0]+
"\n");
}
else {
int x = Integer.parseInt(a[
0]);
int y = Integer.parseInt(a[
1]);
g = contentPanel1.getGraphics();
g.fillOval(x, y,
1,
1);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
MyThread myRunnable =
new MyThread();
myRunnable.setSocket(socket);
Thread thread =
new Thread(myRunnable);
thread.start();
}
}
}