用java多线程实现服务器与客户端原理

用java多线程实现服务器与客户端原理,第1张

服务器端:

import java.awt.*

import java.awt.event.*

import javax.swing.*

import java.io.*

import java.net.*

import java.util.Vector

public class OneToMoreServer extends JFrame implements ActionListener{

JPanel contentPane

JLabel jLabel2 = new JLabel()

JTextField jTextField2 = new JTextField("4700")

JButton jButton1 = new JButton()

JLabel jLabel3 = new JLabel()

JTextField jTextField3 = new JTextField()

JButton jButton2 = new JButton()

JScrollPane jScrollPane1 = new JScrollPane()

JTextArea jTextArea1 = new JTextArea()

ServerSocket server = null

Socket socket = nullBufferedReader instr =nullPrintWriter os=null

Vector vector=new Vector()

boolean serverRun=true

boolean clientRun=true

//Construct the frame

public OneToMoreServer() {

jbInit()

}

class MyThread extends Thread{//该线程负责接收数据

Socket socketI=null

BufferedReader br=null

public MyThread(Socket socket)

{

socketI=socket

}

public void run(){

try{

while(clientRun){

this.sleep(100)

br= new BufferedReader(new InputStreamReader(socketI.getInputStream()))

if(br.ready()){ //检查是否有数据

jTextArea1.append("接收到来自客户端("+socketI.getInetAddress().toString()+")的消息: "+br.readLine()+"\n")

}

}

}catch(Exception ex){JOptionPane.showMessageDialog(null,ex.toString())}

}

}

public void actionPerformed(ActionEvent e){

if(e.getSource()==jButton1){

int port=Integer.parseInt(jTextField2.getText().trim())

//监听指定端口

try

{

server = new ServerSocket(port)

new Thread(new ListenClient()).start()

}

catch(IOException ex)

{

JOptionPane.showMessageDialog(null,ex.toString())

}

}

if(e.getSource()==jButton2){

String msg=jTextField3.getText().trim()

if(msg.length()!=0)

sendData("hello")

}

}

//该线程负责监听指定端口

class ListenClient implements Runnable

{

public void run()

{

try{

if(jButton1.getText().trim().equals("侦听")){

jButton1.setText("正在侦听...")

while(serverRun)

{

Socket socketI=server.accept()//有客户端连入时建立一个线程监听客户端发送的消息

vector.add(socketI)

jButton1.setText("正在聊天...")

jTextArea1.append("客户端"+socketI.getInetAddress().toString()+"已经连接到服务器\n")

MyThread t=new MyThread(socketI)

t.start()

}

}

}catch(Exception ex){

JOptionPane.showMessageDialog(null,ex.toString())

}

}

}

private void sendData(String s){//发送数据

try{

for(int i=0i<vector.size()i++)

{

//怎么广播?????

//向每个客户端发送一条消息

Socket socket=(Socket)vector.get(i)

os= new PrintWriter(socket.getOutputStream())

os.println(s)

os.flush()

}

}catch(Exception ex){

}

}

private void jbInit() {

contentPane = (JPanel) this.getContentPane()

contentPane.setLayout(null)

this.setSize(new Dimension(540, 340))

this.setTitle("服务器")

jLabel2.setBounds(new Rectangle(22, 27, 72, 28))

jLabel2.setText("端口号")

jLabel2.setFont(new java.awt.Font("宋体", 0, 14))

jTextField2.setBounds(new Rectangle(113, 27, 315, 24))

jButton1.setBounds(new Rectangle(440, 28, 73, 25))

jButton1.setFont(new java.awt.Font("Dialog", 0, 14))

jButton1.setBorder(BorderFactory.createEtchedBorder())

jButton1.setActionCommand("jButton1")

jButton1.setText("侦听")

jLabel3.setBounds(new Rectangle(23, 57, 87, 28))

jLabel3.setText("请输入信息")

jLabel3.setFont(new java.awt.Font("宋体", 0, 14))

jTextField3.setBounds(new Rectangle(114, 60, 314, 24))

jTextField3.setText("")

jButton2.setText("广播")

jButton2.setActionCommand("jButton1")

jButton2.setBorder(BorderFactory.createEtchedBorder())

jButton2.setFont(new java.awt.Font("Dialog", 0, 14))

jButton2.setBounds(new Rectangle(440, 58, 73, 25))

jScrollPane1.setBounds(new Rectangle(23, 92, 493, 189))

contentPane.add(jTextField2, null)

contentPane.add(jButton1, null)

contentPane.add(jLabel3, null)

contentPane.add(jTextField3, null)

contentPane.add(jButton2, null)

contentPane.add(jScrollPane1, null)

contentPane.add(jLabel2, null)

jScrollPane1.getViewport().add(jTextArea1, null)

jButton1.addActionListener(this)

jButton2.addActionListener(this)

this.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){

try{

socket.close()

instr.close()

System.exit(0)

}catch(Exception ex){

//JOptionPane.showMessageDialog(null,ex.toString())

}

}

})

}

public static void main(String arg[]){

JFrame.setDefaultLookAndFeelDecorated(true)

OneToMoreServer frm=new OneToMoreServer()

frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)

frm.setVisible(true)

}

}

客户端

import java.awt.*

import java.awt.event.*

import javax.swing.*

import java.io.*

import java.net.*

public class Client extends JFrame implements ActionListener{

JPanel contentPane

JLabel jLabel1 = new JLabel()

JTextField jTextField1 = new JTextField("127.0.0.1")

JLabel jLabel2 = new JLabel()

JTextField jTextField2 = new JTextField("4700")

JButton jButton1 = new JButton()

JLabel jLabel3 = new JLabel()

JTextField jTextField3 = new JTextField()

JButton jButton2 = new JButton()

JScrollPane jScrollPane1 = new JScrollPane()

JTextArea jTextArea1 = new JTextArea()

BufferedReader instr =null

Socket socket = null

PrintWriter os=null

public Client() {

jbInit()

}

class MyThread extends Thread{

public void run(){

try{

os=new PrintWriter(socket.getOutputStream())

instr=new BufferedReader(new InputStreamReader(socket.getInputStream()))

while(true)

{

this.sleep(100)

if(instr.ready())

{

jTextArea1.append("接收到来自服务器的消息: "+instr.readLine()+"\n")

}

}

}catch(Exception ex){

JOptionPane.showMessageDialog(null,ex.toString())

}

}

}

public void actionPerformed(ActionEvent e){

if(e.getSource()==jButton1){

String ip=jTextField3.getText().trim()

int port=Integer.parseInt(jTextField2.getText().trim())

connectServer(ip,port)

}

if(e.getSource()==jButton2){

String s=this.jTextField3.getText().trim()

sendData(s)

}

}

private void connectServer(String ip,int port){//连接

try{

if(jButton1.getText().trim().equals("连接")){

jButton1.setText("连接服务器...")

socket=new Socket(ip,port)

jButton1.setText("正在聊天")

MyThread t=new MyThread()

t.start()

}

}catch(Exception ex){

JOptionPane.showMessageDialog(this,ex.toString())

}

}

private void sendData(String s){//发送数据

try{

os = new PrintWriter(socket.getOutputStream())

os.println(s)

os.flush()

this.jTextArea1.append("向服务器发送消息:"+s+"\n")

}catch(Exception ex){

JOptionPane.showMessageDialog(this,ex.toString())

}

}

private void jbInit() {

contentPane = (JPanel) this.getContentPane()

jLabel1.setFont(new java.awt.Font("宋体", 0, 14))

jLabel1.setText("服务器名称")

jLabel1.setBounds(new Rectangle(20, 22, 87, 28))

contentPane.setLayout(null)

this.setSize(new Dimension(540, 340))

this.setTitle("客户端")

jTextField1.setBounds(new Rectangle(114, 26, 108, 24))

jLabel2.setBounds(new Rectangle(250, 25, 72, 28))

jLabel2.setText("端口号")

jLabel2.setFont(new java.awt.Font("宋体", 0, 14))

jTextField2.setBounds(new Rectangle(320, 27, 108, 24))

jButton1.setBounds(new Rectangle(440, 28, 73, 25))

jButton1.setFont(new java.awt.Font("Dialog", 0, 14))

jButton1.setBorder(BorderFactory.createEtchedBorder())

jButton1.setActionCommand("jButton1")

jButton1.setText("连接")

jLabel3.setBounds(new Rectangle(23, 57, 87, 28))

jLabel3.setText("请输入信息")

jLabel3.setFont(new java.awt.Font("宋体", 0, 14))

jTextField3.setBounds(new Rectangle(114, 60, 314, 24))

jButton2.setText("发送")

jButton2.setActionCommand("jButton1")

jButton2.setBorder(BorderFactory.createEtchedBorder())

jButton2.setFont(new java.awt.Font("Dialog", 0, 14))

jButton2.setBounds(new Rectangle(440, 58, 73, 25))

jScrollPane1.setBounds(new Rectangle(23, 92, 493, 189))

contentPane.add(jLabel1, null)

contentPane.add(jTextField1, null)

contentPane.add(jLabel2, null)

contentPane.add(jTextField2, null)

contentPane.add(jButton1, null)

contentPane.add(jLabel3, null)

contentPane.add(jTextField3, null)

contentPane.add(jButton2, null)

contentPane.add(jScrollPane1, null)

jScrollPane1.getViewport().add(jTextArea1, null)

jButton1.addActionListener(this)

jButton2.addActionListener(this)

this.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){

try{

socket.close()instr.close()os.close()System.exit(0)

}catch(Exception ex){

JOptionPane.showMessageDialog(null,ex.toString())

}

}

})

}

public static void main(String arg[]){

JFrame.setDefaultLookAndFeelDecorated(true)

Client frm=new Client()

frm.setVisible(true)

}

}

程序分Server和Client

服务器端打开侦听的端口,一有客户端连接就创建两个新的线程来负责这个连接

一个负责客户端发送的信息(ClientMsgCollectThread 类),

另一个负责通过该Socket发送数据(ServerMsgSendThread )

Server.java代码如下:

/*

* 创建日期 2009-3-7

*

* TODO 要更改此生成的文件的模板,请转至

* 窗口 - 首选项 - Java - 代码样式 - 代码模板

*/

package faue.MutiUser

import java.io.BufferedReader

import java.io.IOException

import java.io.InputStreamReader

import java.io.PrintWriter

import java.net.ServerSocket

import java.net.Socket

/**

* 服务器端

*

* @author Faue

*/

public class Server extends ServerSocket {

private static final int SERVER_PORT = 10000

/**

* 构造方法,用于实现连接的监听

*

* @throws IOException

*/

public Server() throws IOException {

super(SERVER_PORT)

try {

while (true) {

Socket socket = super.accept()

new Thread(new ClientMsgCollectThread(socket), "getAndShow"

+ socket.getPort()).start()

new Thread(new ServerMsgSendThread(socket), "send"

+ socket.getPort()).start()

}

} catch (IOException e) {

e.printStackTrace()

}

}

public static void main(String[] args) throws IOException {

new Server()

}

/**

* 该类用于创建接收客户端发来的信息并显示的线程

*

* @author Faue

* @version 1.0.0

*/

class ClientMsgCollectThread implements Runnable {

private Socket client

private BufferedReader in

private StringBuffer inputStringBuffer = new StringBuffer("Hello")

/**

* 得到Socket的输入流

*

* @param s

* @throws IOException

*/

public ClientMsgCollectThread(Socket s) throws IOException {

client = s

in = new BufferedReader(new InputStreamReader(client

.getInputStream(), "GBK"))

}

public void run() {

try {

while (!client.isClosed()) {

inputStringBuffer.delete(0, inputStringBuffer.length())

inputStringBuffer.append(in.readLine())

System.out.println(getMsg(inputStringBuffer.toString()))

}

} catch (IOException e) {

//e.printStackTrace()

System.out.println(client.toString() + " is closed!")

}

}

/**

* 构造显示的字符串

*

* @param line

* @return

*/

private String getMsg(String line) {

return client.toString() + " says:" + line

}

}

/**

* 该类用于创建发送数据的线程

*

* @author Faue

* @version 1.0.0

*/

class ServerMsgSendThread implements Runnable {

private Socket client

private PrintWriter out

private BufferedReader keyboardInput

private StringBuffer outputStringBuffer = new StringBuffer("Hello")

/**

* 得到键盘的输入流

*

* @param s

* @throws IOException

*/

public ServerMsgSendThread(Socket s) throws IOException {

client = s

out = new PrintWriter(client.getOutputStream(), true)

keyboardInput = new BufferedReader(new InputStreamReader(System.in))

}

public void run() {

try {

while (!client.isClosed()) {

outputStringBuffer.delete(0, outputStringBuffer.length())

outputStringBuffer.append(keyboardInput.readLine())

out.println(outputStringBuffer.toString())

}

} catch (IOException e) {

//e.printStackTrace()

System.out.println(client.toString() + " is closed!")

}

}

}

}

客户端:

实现基于IP地址的连接,连接后也创建两个线程来实现信息的发送和接收

/*

* 创建日期 2009-3-7

*

*/

package faue.MutiUser

import java.io.BufferedReader

import java.io.IOException

import java.io.InputStreamReader

import java.io.PrintWriter

import java.net.Socket

/**

* 客户端

*

* @author Faue

*/

public class Client {

private Socket mySocket

/**

* 创建线程的构造方法

*

* @param IP

* @throws IOException

*/

public Client(String IP) throws IOException {

try {

mySocket = new Socket(IP, 10000)

new Thread(new ServerMsgCollectThread(mySocket), "getAndShow"

+ mySocket.getPort()).start()

new Thread(new ClientMsgSendThread(mySocket), "send"

+ mySocket.getPort()).start()

} catch (IOException e) {

//e.printStackTrace()

System.out.println("Server.IP:" + IP

+ " port:10000 can not be Connected")

}

}

public static void main(String[] args) throws IOException {

try {

new Client(args[0])

} catch (Exception e) {

System.out.println("输入的IP地址错误")

}

}

/**

* 该类用于创建接收服务端发来的信息并显示的线程

*

* @author Faue

* @version 1.0.0

*/

class ServerMsgCollectThread implements Runnable {

private Socket client

private BufferedReader in

private StringBuffer inputStringBuffer = new StringBuffer("Hello")

/**

* 得到Socket的输入流

*

* @param s

* @throws IOException

*/

public ServerMsgCollectThread(Socket s) throws IOException {

client = s

in = new BufferedReader(new InputStreamReader(client

.getInputStream(), "GBK"))

}

public void run() {

try {

while (!client.isClosed()) {

inputStringBuffer.delete(0, inputStringBuffer.length())

inputStringBuffer.append(in.readLine())

System.out.println(getMsg(inputStringBuffer.toString()))

}

} catch (IOException e) {

//e.printStackTrace()

System.out.println(client.toString() + " is closed!")

System.exit(0)

}

}

/**

* 构造输入字符串

*

* @param line

* @return

*/

private String getMsg(String line) {

return client.toString() + " says:" + line

}

}

/**

* 该类用于创建发送数据的线程

*

* @author Faue

* @version 1.0.0

*/

class ClientMsgSendThread implements Runnable {

private Socket client

private PrintWriter out

private BufferedReader keyboardInput

private StringBuffer outputStringBuffer = new StringBuffer("Hello")

/**

* 得到键盘的输入流

*

* @param s

* @throws IOException

*/

public ClientMsgSendThread(Socket s) throws IOException {

client = s

out = new PrintWriter(client.getOutputStream(), true)

keyboardInput = new BufferedReader(new InputStreamReader(System.in))

}

public void run() {

try {

while (!client.isClosed()) {

outputStringBuffer.delete(0, outputStringBuffer.length())

outputStringBuffer.append(keyboardInput.readLine())

out.println(outputStringBuffer.toString())

}

out.println("--- See you, bye! ---")

} catch (IOException e) {

//e.printStackTrace()

System.out.println(client.toString() + " is closed!")

System.exit(0)

}

}

}

}

如果对您有帮助,请记得采纳为满意答案,谢谢!祝您生活愉快!

vaela

import java.io.PrintWriter

import java.net.ServerSocket

import java.net.Socket

public class Test {

public static void main(String[] args) throws Exception {

ServerSocket server = new ServerSocket(888)

while(true) {

Socket s = server.accept()

Processer p = new Processer(s)

Thread t = new Thread(p)

t.start()

}

}

}

class Processer implements Runnable {

private Socket socket

public Processer(Socket s) {

// TODO Auto-generated constructor stub

this.socket = s

}

@Override

public void run() {

try {

PrintWriter out=new PrintWriter(socket.getOutputStream(),true)

out.println("HTTP/1.0 200 OK")

out.println("Content-Type:text/htmlcharset=utf-8")

out.println()

out.println("<h1>Web服务器测试成功!</h1>")

out.close()

} catch(Exception ex) {

ex.printStackTrace()

} finally {

try {

socket.close()

} catch (Exception e) {

e.printStackTrace()

}

}

}

}


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/209548.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-04
下一篇2023-04-04

发表评论

登录后才能评论

评论列表(0条)

    保存