用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)

}

}

SMTP 建立在TCP之上 可以用传统的方式,建立socket 然后 accept 到一个请求后 新建一个线程处理 rec 和send 数据即可

这种方式吞吐量不够,可使用Java nio 中的select的模型,两个线程就ok


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

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

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

发表评论

登录后才能评论

评论列表(0条)

    保存