`
hz_chenwenbiao
  • 浏览: 998212 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

socket通信编程

阅读更多

    昨天同学问了一个关于socket通信编程的程序,花了我一晚时间去修改,才将它改好。这个程序主要是做一个服务端接收处理多个客户端请求的例程,具体如下代码所示,挺好的学习例子:

server.java

/*
 * server.java
 *
 * Created on __DATE__, __TIME__
 */

package socket_;

import java.awt.event.KeyEvent;
import java.io.*;
import java.net.*;

//import socket_.SocketServer.Getinfo;

/**
 * 
 * @author __USER__
 */
public class server extends javax.swing.JFrame  implements Runnable{// 继承runnable之后,通过Runnable接口来实现多线程的功能

	private ServerSocket serverSocket;
	private Socket socket;
	private boolean hasStart;//是否开启服务器的标志
	
	/** Creates new form server */
	public server() {
		initComponents();
		hasStart = false;
		try {
			serverSocket = new ServerSocket(10000);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	// GEN-BEGIN:initComponents
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {

		jScrollPane1 = new javax.swing.JScrollPane();
		jTextArea1 = new javax.swing.JTextArea();
		jLabel1 = new javax.swing.JLabel();
		jButton1 = new javax.swing.JButton();
		jTextField1 = new javax.swing.JTextField();
		jButton2 = new javax.swing.JButton();
		jButton3 = new javax.swing.JButton();

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		setTitle("\u670d\u52a1\u5668");

		jTextArea1.setColumns(20);
		jTextArea1.setRows(5);
		jScrollPane1.setViewportView(jTextArea1);

		jLabel1.setText("\u53d1\u9001");

		jButton1.setText("\u542f\u52a8");
		jButton1.setActionCommand("jButton1");
		jButton1.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton1ActionPerformed(evt);
			}
		});

		jButton2.setText("\u53d1\u9001");
		jButton2.setActionCommand("jButton2");
		jButton2.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton2ActionPerformed(evt);
			}
		});

		jButton3.setText("\u9000\u51fa");
		jButton3.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton3ActionPerformed(evt);
			}
		});

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
				getContentPane());
		getContentPane().setLayout(layout);
		layout
				.setHorizontalGroup(layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								layout
										.createSequentialGroup()
										.addGap(18, 18, 18)
										.addGroup(
												layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING)
														.addGroup(
																layout
																		.createSequentialGroup()
																		.addComponent(
																				jButton1)
																		.addGap(
																				139,
																				139,
																				139)
																		.addComponent(
																				jButton2)
																		.addPreferredGap(
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED,
																				161,
																				Short.MAX_VALUE)
																		.addComponent(
																				jButton3))
														.addGroup(
																layout
																		.createSequentialGroup()
																		.addComponent(
																				jLabel1)
																		.addGap(
																				26,
																				26,
																				26)
																		.addComponent(
																				jTextField1,
																				javax.swing.GroupLayout.DEFAULT_SIZE,
																				421,
																				Short.MAX_VALUE))
														.addComponent(
																jScrollPane1,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																471,
																javax.swing.GroupLayout.PREFERRED_SIZE))
										.addContainerGap(19, Short.MAX_VALUE)));
		layout
				.setVerticalGroup(layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								layout
										.createSequentialGroup()
										.addContainerGap()
										.addComponent(
												jScrollPane1,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												239,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addGap(29, 29, 29)
										.addGroup(
												layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(jLabel1)
														.addComponent(
																jTextField1,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE))
										.addGap(18, 18, 18)
										.addGroup(
												layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(jButton1)
														.addComponent(jButton3)
														.addComponent(jButton2))
										.addContainerGap(28, Short.MAX_VALUE)));

		pack();
	}// </editor-fold>

	// GEN-END:initComponents

	
	private class CreateSocket extends Thread{
		private Socket socket;
		private BufferedReader bufferedReader;
		private PrintWriter printWriter;
		
		
		public CreateSocket(Socket socket){
			this.socket = socket;
			try {
				bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}


		@Override
		public void run() {
//			printWriter.print(b)
			String temp;
			
			try {
				temp = bufferedReader.readLine();
				
				while(!"exit".equals(temp))
				{
					jTextArea1.append("服务器接收到客户" + socket.getLocalPort() + ":" + socket.getPort() + "的消息:"  + temp + "\n");
//					jTextArea1.setCaretPosition(jTextArea1.getText().length());//设置新加入的数据显示出来,滚动条向下滑
				
					//休眠一下再试读下一条
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					
					temp = bufferedReader.readLine();
				}
			} catch (IOException e) {
				e.printStackTrace();
				jTextArea1.append(e.toString() + "\n");
			}
			
			try {
				bufferedReader.close();
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
				jTextArea1.append(e.getStackTrace() + "\n");
			}

		}
		
	}

	private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
		/*try {
			jTextArea1.append("服务器退出!\n");
			printWriter.println("exit");
			printWriter.flush();
		} catch (Exception e) {
			jTextArea1.append(e.toString() + "\n");

		} finally {
			System.exit(0);
		}*/
		
		System.exit(0);
	}

	private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
/*
		try {

			// printWriter需要分配空间
			printWriter.println(jTextField1.getText());
			printWriter.flush();
			jTextArea1.append("服务器端消息:" + jTextField1.getText() + "\n");// .append("服务器端消息:"
																		// +
																		// jTextField1.getText());
			jTextField1.setText("");

		} catch (Exception e) {
			System.out.println("run error");
			jTextArea1.append(e.toString() + "\n");

		}*/
	}

	
	private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
		
		if(hasStart) return;
		hasStart = true;
		
		jTextArea1.append("服务器已启动!" + "\n");
		jTextArea1.setCaretPosition(jTextArea1.getText().length());
		//再开启一个线程,因为主线程要用来作界面的显示。如果这里没用线程而直接开启serverSocket的监听,那就会在界面上看不到效果,因为主线程一直在做监听工作
		
		Thread thread = new Thread(this);
		thread.start();
		
		
//		for (int i = 0; i < 10; i++) {
//			Thread thread = new Thread(this); // 关键性,启动一个任务
//			thread.start();
//		}
	}
	
	@Override
	public void run() {
		while(true)
		{
			try {
				socket = serverSocket.accept();
			} catch (IOException e) {
				e.printStackTrace();
			}
			CreateSocket createSocket = new CreateSocket(socket);
			createSocket.start();
		}
	}
	

	/**
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new server().setVisible(true);
			}
		});
	}

	// Variables declaration - do not modify
	private javax.swing.JButton jButton1;
	private javax.swing.JButton jButton2;
	private javax.swing.JButton jButton3;
	private javax.swing.JLabel jLabel1;
	private javax.swing.JScrollPane jScrollPane1;
	private javax.swing.JTextArea jTextArea1;
	private javax.swing.JTextField jTextField1;
	// End of variables declaration//GEN-END:variables

	

}

 

 

Client.java

/*
 * Client.java
 *
 * Created on __DATE__, __TIME__
 */

package socket_;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

//import socket_.SocketClient.Getinfo;

/**
 *
 * @author  __USER__
 */
public class Client extends javax.swing.JFrame  {

	Socket socket;
	BufferedReader bufferedReader;
	PrintWriter printWriter;//=new PrintWriter("dasasadasdasd");

	/** Creates new form Client */
	public Client() {
		initComponents();
	}

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	//GEN-BEGIN:initComponents
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {

		jScrollPane1 = new javax.swing.JScrollPane();
		jTextArea1 = new javax.swing.JTextArea();
		jLabel1 = new javax.swing.JLabel();
		jTextField1 = new javax.swing.JTextField();
		jButton1 = new javax.swing.JButton();
		jButton2 = new javax.swing.JButton();
		jButton3 = new javax.swing.JButton();

		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
		setTitle("\u5ba2\u6237\u7aef");

		jTextArea1.setColumns(20);
		jTextArea1.setRows(5);
		jScrollPane1.setViewportView(jTextArea1);

		jLabel1.setText("jLabel1");

		jTextField1.setText("jTextField1");

		jButton1.setText("\u8fde\u63a5");
		jButton1.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton1ActionPerformed(evt);
			}
		});

		jButton2.setText("\u53d1\u9001");
		jButton2.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton2ActionPerformed(evt);
			}
		});

		jButton3.setText("\u9000\u51fa");
		jButton3.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton3ActionPerformed(evt);
			}
		});

		javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
				getContentPane());
		getContentPane().setLayout(layout);
		layout
				.setHorizontalGroup(layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								layout
										.createSequentialGroup()
										.addGap(19, 19, 19)
										.addGroup(
												layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.LEADING)
														.addComponent(
																jScrollPane1,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																482,
																Short.MAX_VALUE)
														.addGroup(
																javax.swing.GroupLayout.Alignment.TRAILING,
																layout
																		.createSequentialGroup()
																		.addComponent(
																				jLabel1)
																		.addGap(
																				18,
																				18,
																				18)
																		.addComponent(
																				jTextField1,
																				javax.swing.GroupLayout.DEFAULT_SIZE,
																				422,
																				Short.MAX_VALUE))
														.addGroup(
																layout
																		.createSequentialGroup()
																		.addComponent(
																				jButton1)
																		.addGap(
																				149,
																				149,
																				149)
																		.addComponent(
																				jButton2)
																		.addPreferredGap(
																				javax.swing.LayoutStyle.ComponentPlacement.RELATED,
																				162,
																				Short.MAX_VALUE)
																		.addComponent(
																				jButton3)))
										.addContainerGap()));
		layout
				.setVerticalGroup(layout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								layout
										.createSequentialGroup()
										.addGap(21, 21, 21)
										.addComponent(
												jScrollPane1,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												234,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addGap(18, 18, 18)
										.addGroup(
												layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(jLabel1)
														.addComponent(
																jTextField1,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE))
										.addGap(41, 41, 41)
										.addGroup(
												layout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.BASELINE)
														.addComponent(jButton1)
														.addComponent(jButton3)
														.addComponent(jButton2))
										.addContainerGap(30, Short.MAX_VALUE)));

		pack();
	}

	

	private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
		try {
			jTextArea1.append("服务器退出!\n");
			printWriter.println("exit");
			printWriter.flush();
		} catch (Exception e) {
			jTextArea1.append(e.toString() + "\n");

			
		} finally {
			System.exit(0);
		}
	}

	private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
		try {
			printWriter.println(jTextField1.getText());
			printWriter.flush();
			jTextArea1.append("客户器端发送消息:" + jTextField1.getText() + "\n");// .append("服务器端消息:" + jTextField1.getText());
			jTextField1.setText("");
			jTextField1.grabFocus();//获取焦点
		} catch (Exception e) {
			System.out.println("send error");
			jTextArea1.append(e.toString() + "\n");
			
		}
	}

	private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
		try {
			socket = new Socket(InetAddress.getLocalHost(), 10000);
			jTextArea1.append("客户端已加入 \n");
			bufferedReader = new BufferedReader(new InputStreamReader(socket
					.getInputStream()));
			printWriter = new PrintWriter(socket.getOutputStream());
			jButton2.setEnabled(true);
			
		} catch (Exception e) {
			
			jTextArea1.append(e.toString() + "\n");
		}
	}

	/**
	 * @param args the command line arguments
	 */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new Client().setVisible(true);
			}
		});
	}

	//GEN-BEGIN:variables
	// Variables declaration - do not modify
	private javax.swing.JButton jButton1;
	private javax.swing.JButton jButton2;
	private javax.swing.JButton jButton3;
	private javax.swing.JLabel jLabel1;
	private javax.swing.JScrollPane jScrollPane1;
	private javax.swing.JTextArea jTextArea1;
	private javax.swing.JTextField jTextField1;
	// End of variables declaration//GEN-END:variables
}




 

要注意的就是用多线程的时候一定要有fork-join模型在脑子里:也就是我们要控制一个主线程(界面一般要做主线程,不然无法保持显示最新信息,而是处于像缰死的状态),然后分出子线程去完成所要的工作,最后再归到主线程。对于多个客户端的请求,服务端要对每个客户的请求都开一个新的socket和新的bufferedReader及新的printWriter用于与每个客户交互,不能共用。我们可以在多次运行client.java类,模拟多个客户端,我们从服务器端打印出来的信息可以看到客户端的端口号是不同的,因为对同一台机子的应用的区分就是靠端口来区分的。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics