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

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

服务器端:
import javaawt;
import javaawtevent;
import javaxswing;
import javaio;
import javanet;
import javautilVector;
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 = null;BufferedReader instr =null;PrintWriter 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){
thissleep(100);
br= new BufferedReader(new InputStreamReader(socketIgetInputStream()));
if(brready()){ //检查是否有数据
jTextArea1append("接收到来自客户端("+socketIgetInetAddress()toString()+")的消息: "+brreadLine()+"\n");
}
}
}catch(Exception ex){JOptionPaneshowMessageDialog(null,extoString());}
}
}

public void actionPerformed(ActionEvent e){
if(egetSource()==jButton1){
int port=IntegerparseInt(jTextField2getText()trim());
//监听指定端口
try
{
server = new ServerSocket(port);
new Thread(new ListenClient())start();
}
catch(IOException ex)
{
JOptionPaneshowMessageDialog(null,extoString());
}
}
if(egetSource()==jButton2){
String msg=jTextField3getText()trim();
if(msglength()!=0)
sendData("hello");
}
}
//该线程负责监听指定端口
class ListenClient implements Runnable
{
public void run()
{
try{
if(jButton1getText()trim()equals("侦听")){
jButton1setText("正在侦听");
while(serverRun)
{
Socket socketI=serveraccept();//有客户端连入时建立一个线程监听客户端发送的消息
vectoradd(socketI);
jButton1setText("正在聊天");
jTextArea1append("客户端"+socketIgetInetAddress()toString()+"已经连接到服务器\n");
MyThread t=new MyThread(socketI);
tstart();
}
}
}catch(Exception ex){
JOptionPaneshowMessageDialog(null,extoString());
}
}
}
private void sendData(String s){//发送数据
try{
for(int i=0;i<vectorsize();i++)
{
//怎么广播
//向每个客户端发送一条消息
Socket socket=(Socket)vectorget(i);
os= new PrintWriter(socketgetOutputStream());
osprintln(s);
osflush();
}
}catch(Exception ex){
}
}
private void jbInit() {
contentPane = (JPanel) thisgetContentPane();
contentPanesetLayout(null);
thissetSize(new Dimension(540, 340));
thissetTitle("服务器");
jLabel2setBounds(new Rectangle(22, 27, 72, 28));
jLabel2setText("端口号");
jLabel2setFont(new javaawtFont("宋体", 0, 14));
jTextField2setBounds(new Rectangle(113, 27, 315, 24));

jButton1setBounds(new Rectangle(440, 28, 73, 25));
jButton1setFont(new javaawtFont("Dialog", 0, 14));
jButton1setBorder(BorderFactorycreateEtchedBorder());
jButton1setActionCommand("jButton1");
jButton1setText("侦听");
jLabel3setBounds(new Rectangle(23, 57, 87, 28));
jLabel3setText("请输入信息");
jLabel3setFont(new javaawtFont("宋体", 0, 14));
jTextField3setBounds(new Rectangle(114, 60, 314, 24));
jTextField3setText("");
jButton2setText("广播");
jButton2setActionCommand("jButton1");
jButton2setBorder(BorderFactorycreateEtchedBorder());
jButton2setFont(new javaawtFont("Dialog", 0, 14));
jButton2setBounds(new Rectangle(440, 58, 73, 25));
jScrollPane1setBounds(new Rectangle(23, 92, 493, 189));

contentPaneadd(jTextField2, null);
contentPaneadd(jButton1, null);
contentPaneadd(jLabel3, null);
contentPaneadd(jTextField3, null);
contentPaneadd(jButton2, null);
contentPaneadd(jScrollPane1, null);
contentPaneadd(jLabel2, null);
jScrollPane1getViewport()add(jTextArea1, null);
jButton1addActionListener(this);
jButton2addActionListener(this);
thisaddWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
try{
socketclose();
instrclose();
Systemexit(0);
}catch(Exception ex){
//JOptionPaneshowMessageDialog(null,extoString());
}

}
});
}
public static void main(String arg[]){
JFramesetDefaultLookAndFeelDecorated(true);
OneToMoreServer frm=new OneToMoreServer();
frmsetDefaultCloseOperation(JFrameEXIT_ON_CLOSE);
frmsetVisible(true);
}
}
客户端
import javaawt;
import javaawtevent;
import javaxswing;
import javaio;
import javanet;
public class Client extends JFrame implements ActionListener{
JPanel contentPane;
JLabel jLabel1 = new JLabel();
JTextField jTextField1 = new JTextField("127001");
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(socketgetOutputStream());
instr=new BufferedReader(new InputStreamReader(socketgetInputStream()));
while(true)
{
thissleep(100);
if(instrready())
{
jTextArea1append("接收到来自服务器的消息: "+instrreadLine()+"\n");
}
}
}catch(Exception ex){
JOptionPaneshowMessageDialog(null,extoString());
}
}
}
public void actionPerformed(ActionEvent e){
if(egetSource()==jButton1){
String ip=jTextField3getText()trim();
int port=IntegerparseInt(jTextField2getText()trim());
connectServer(ip,port);
}
if(egetSource()==jButton2){
String s=thisjTextField3getText()trim();
sendData(s);
}
}
private void connectServer(String ip,int port){//连接
try{
if(jButton1getText()trim()equals("连接")){
jButton1setText("连接服务器");
socket=new Socket(ip,port);
jButton1setText("正在聊天");
MyThread t=new MyThread();
tstart();
}
}catch(Exception ex){
JOptionPaneshowMessageDialog(this,extoString());
}
}
private void sendData(String s){//发送数据
try{
os = new PrintWriter(socketgetOutputStream());
osprintln(s);
osflush();
thisjTextArea1append("向服务器发送消息:"+s+"\n");
}catch(Exception ex){
JOptionPaneshowMessageDialog(this,extoString());
}
}
private void jbInit() {
contentPane = (JPanel) thisgetContentPane();
jLabel1setFont(new javaawtFont("宋体", 0, 14));
jLabel1setText("服务器名称");
jLabel1setBounds(new Rectangle(20, 22, 87, 28));
contentPanesetLayout(null);
thissetSize(new Dimension(540, 340));
thissetTitle("客户端");

jTextField1setBounds(new Rectangle(114, 26, 108, 24));
jLabel2setBounds(new Rectangle(250, 25, 72, 28));
jLabel2setText("端口号");
jLabel2setFont(new javaawtFont("宋体", 0, 14));
jTextField2setBounds(new Rectangle(320, 27, 108, 24));

jButton1setBounds(new Rectangle(440, 28, 73, 25));
jButton1setFont(new javaawtFont("Dialog", 0, 14));
jButton1setBorder(BorderFactorycreateEtchedBorder());
jButton1setActionCommand("jButton1");
jButton1setText("连接");
jLabel3setBounds(new Rectangle(23, 57, 87, 28));
jLabel3setText("请输入信息");
jLabel3setFont(new javaawtFont("宋体", 0, 14));
jTextField3setBounds(new Rectangle(114, 60, 314, 24));

jButton2setText("发送");
jButton2setActionCommand("jButton1");
jButton2setBorder(BorderFactorycreateEtchedBorder());
jButton2setFont(new javaawtFont("Dialog", 0, 14));
jButton2setBounds(new Rectangle(440, 58, 73, 25));
jScrollPane1setBounds(new Rectangle(23, 92, 493, 189));

contentPaneadd(jLabel1, null);
contentPaneadd(jTextField1, null);
contentPaneadd(jLabel2, null);
contentPaneadd(jTextField2, null);
contentPaneadd(jButton1, null);
contentPaneadd(jLabel3, null);
contentPaneadd(jTextField3, null);
contentPaneadd(jButton2, null);
contentPaneadd(jScrollPane1, null);
jScrollPane1getViewport()add(jTextArea1, null);
jButton1addActionListener(this);
jButton2addActionListener(this);
thisaddWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
try{
socketclose();instrclose();osclose();Systemexit(0);
}catch(Exception ex){
JOptionPaneshowMessageDialog(null,extoString());
}
}
});
}
public static void main(String arg[]){
JFramesetDefaultLookAndFeelDecorated(true);
Client frm=new Client();
frmsetVisible(true);
}
}

服务器端代码:
import javaioBufferedReader;
import javaioIOException;
import javaioInputStreamReader;
import javaioPrintStream;
import javanetServerSocket;
import javanetSocket;
/
Socket通讯服务器端
@author 米强

/
public class ServerMain {
public ServerMain() {
try {
// 构造服务器ServerSocket对象,参数为服务器端开放的端口号
ServerSocket ss = new ServerSocket(30102);
Systemoutprintln("服务器准备就绪!");
// 死循环可以使服务器持续处于接收客户端状态
while(true){
// 该方法使程序阻塞,等待客户端的链接,当监听到客户端的链接,创建一个Socket对象与客户端单独会话
Socket s = ssaccept();
// 为了不影响服务器监听其它客户端,这里开启了一个线程,由线程处理与这个客户端的会话
new ServerThread(s)start();
}
} catch (IOException e) {
eprintStackTrace();
}
}
public static void main(String[] args) {
new ServerMain();
}
}
/
服务器端与客户端会话的线程
/
class ServerThread extends Thread {
private Socket s = null;
private BufferedReader read = null;
private PrintStream print = null;
public ServerThread(Socket s) {
thiss = s;
try {
// 从Socket中获取输入流和输出流,由于我们只做一个简单的字符串通讯,所以采用BufferedRead和PrintStream来封装输入、输出流
read = new BufferedReader(new InputStreamReader(sgetInputStream()));
print = new PrintStream(sgetOutputStream());
} catch (IOException e) {
eprintStackTrace();
}
}
/
线程的运行run方法
/
public void run() {
try {
String message = null;
// 这里循环可以使服务器持续的接收客户端信息。readreadLine()通过输入流读取一段字符串,赋值给message变量,如果message字符串不为“exit”则循环,否则结束循环
while (!(message = readreadLine())equals("exit")){
// 将字符串前面添加“返回:”,再发回客户端
printprintln("返回:" + message);
}
} catch (IOException e) {
} finally {
// 在 finally 代码块中无论如何都会执行下面代码:
try {
// 如果没有关闭Socket
if(!sisClosed()){
// 关闭Socket链接
sclose();
}
} catch (IOException e1) {
e1printStackTrace();
}
}
}
}
客户端代码:
import javaioBufferedReader;
import javaioIOException;
import javaioInputStreamReader;
import javaioPrintStream;
import javanetSocket;
import javanetUnknownHostException;
import javautilScanner;
/
Socket通讯客户端
@author 米强

/
public class ClientMain {
public ClientMain() {
try {
// 构造与服务器通讯的Socket对象,参数为服务器IP地址(String)和端口号(int),端口号需要和服务器端开放的端口号对应
Socket s = new Socket("1921681100", 30102);
// 启动一个线程与服务器通讯,并把链接服务器的Socket对象传递过去
new LinkThread(s)start();
} catch (UnknownHostException e) {
eprintStackTrace();
} catch (IOException e) {
eprintStackTrace();
}
}
public static void main(String[] args) {
new ClientMain();
}

}
/
与服务器通讯的线程
/
class LinkThread extends Thread {
private Socket s = null;
// 输出流
private PrintStream out = null;
// 缓冲输入流
private BufferedReader in = null;
// 录入文字的Scanner对象
private Scanner scanner = null;

public LinkThread(Socket s) {
// 将Socket对象实例保存在全局变量中,因为run方法中我们还要用它断开链接
thiss = s;
try {
// 从Socket中获取输入流和输出流,由于我们只做一个简单的字符串通讯,所以采用BufferedRead和PrintStream来封装输入、输出流
out = new PrintStream(sgetOutputStream());
in = new BufferedReader(new InputStreamReader(sgetInputStream()));
} catch (UnknownHostException e) {
eprintStackTrace();
} catch (IOException e) {
eprintStackTrace();
}
}

/
线程的运行run方法
/
public void run() {
// 构造Scanner对象
scanner = new Scanner(Systemin);
Systemoutprintln("提示:如果要结束本次会话,请输入“exit”指令!");
try {
// 死循环可以使客户端不断的向服务器发送信息,不用担心循环无法结束,后面的return语句可以结束整个线程。
while(true){
// 提示用户输入文字
Systemoutprint("请输入:");
// 将用户输入的字符串保存在message变量中
String message = scannernextLine();
// 通过输出流发送字符串
outprintln(message);
// 清空缓冲,强制输出
outflush();
// 获取服务器返回的字符串
String str = inreadLine();
// 如果返回的字符串存在
if(str != null){
// 显示在控制台
Systemoutprintln(str);
}else{
// 提示会话结束,并结束线程
Systemoutprintln("本次会话结束!");
return;
}
}
} catch (IOException e) {
eprintStackTrace();
} finally {
// 在 finally 代码块中无论如何都会执行下面代码:
try {
// 如果没有关闭Socket
if(!sisClosed()){
// 关闭Socket链接
sclose();
}
} catch (IOException e1) {
e1printStackTrace();
}
}
}

}

下面是我自己写的一个读取并显示txt文件的demo,希望对您有帮助。
public class Client {
public static void main(String[] args) {
ClientFrame f = new ClientFrame();
}
}
import javaawtBorderLayout;
import javaawtContainer;
import javaawtDimension;
import javaawtGridLayout;
import javaawtToolkit;
import javaawteventActionEvent;
import javaawteventActionListener;
import javaioDataInputStream;
import javaioDataOutputStream;
import javaioIOException;
import javanetSocket;
import javanetUnknownHostException;
import javautilVector;
import javaxswingBorderFactory;
import javaxswingJButton;
import javaxswingJFrame;
import javaxswingJList;
import javaxswingJScrollPane;
import javaxswingJTextArea;
import javaxswingeventListSelectionEvent;
import javaxswingeventListSelectionListener;
public class ClientFrame extends JFrame implements ActionListener, ListSelectionListener{
private JList list = null;
private JButton sbtn = null;
private JButton cbtn = null;
private Vector v = null;
private JTextArea txt = null;
private Container control = null;
private Container btn = null;
private Socket client = null;
private DataInputStream reader = null;
private DataOutputStream writer = null;

public ClientFrame(){
thislist = new JList();
thislistsetBorder(BorderFactorycreateTitledBorder("文件列表"));
thislistaddListSelectionListener(this);

thissbtn = new JButton("显示");
thissbtnaddActionListener(this);
thiscbtn = new JButton("清除");
thiscbtnaddActionListener(this);

thiscontrol = new Container();
thiscontrolsetPreferredSize(new Dimension(150, 400));
thiscontrolsetLayout(new BorderLayout());
thiscontroladd(new JScrollPane(thislist),BorderLayoutCENTER);
thisbtn = new Container();
thisbtnsetLayout(new GridLayout(1,2));
btnadd(sbtn);
btnadd(cbtn);
thiscontroladd(thisbtn,BorderLayoutSOUTH);

thistxt = new JTextArea();
thistxtsetEditable(false);
thistxtsetSize(350, 400);
thissetTitle("客户端");
thissetSize(500, 400);
thissetVisible(true);
Dimension displaySize = ToolkitgetDefaultToolkit()getScreenSize(); 
thissetLocation((displaySizewidth - thisgetWidth()) / 2, (displaySizeheight - thisgetHeight()) / 2);
thissetLayout(new BorderLayout());
thisadd(thiscontrol,BorderLayoutWEST);
thisadd(new JScrollPane(thistxt),BorderLayoutCENTER);
thissetDefaultCloseOperation(JFrameEXIT_ON_CLOSE);

try {
//thisclient = new Socket("1921683234",6666);
thisclient = new Socket("1921681100",6666);
thisreader = new DataInputStream(clientgetInputStream());
thiswriter = new DataOutputStream(clientgetOutputStream());
} catch (UnknownHostException e) {
eprintStackTrace();
} catch (IOException e) {
eprintStackTrace();
}
}
public void actionPerformed(ActionEvent event){
 if(eventgetSource() == sbtn){
 if(v == null){
 v = new Vector();
 }
 else{
 vclear();
 }
 
 try {  
 writerwriteUTF("getfilelist");
 writerflush();
 String t = readerreadUTF();
 while( t != null && !tequals("")){
 vadd(t);
 t = readerreadUTF();
 }
 } catch (UnknownHostException e) {
 eprintStackTrace();
 } catch (IOException e) {
 eprintStackTrace();
 }
 thislistsetListData(v);
 }
 
 if(eventgetSource() == cbtn){
 thistxtsetText("");
 }
 }
public void valueChanged(ListSelectionEvent e) {
int i = thislistgetSelectedIndex(); 
if (! thislistgetValueIsAdjusting() && i != -1) {
try {
writerwriteUTF("getfilecontent_" + i);
writerflush();
String tmp = readerreadUTF();
thistxtsetText(tmp);
} catch (IOException e1) {
e1printStackTrace();
}
}
}
}
import javaioDataInputStream;
import javaioDataOutputStream;
import javaioFile;
import javaioFileInputStream;
import javaioIOException;
import javaioInputStreamReader;
import javaioReader;
import javanetServerSocket;
import javanetSocket;
import javautilArrayList;
import javautilIterator;
public class Server {
static ArrayList<File> fileArray = new ArrayList<File>();
public static void main(String args[]) {
ServerSocket server = null;
Socket client = null;
String cmd = "";
try {
server = new ServerSocket(6666);
client = serveraccept();

DataInputStream reader = new DataInputStream(clientgetInputStream());
DataOutputStream writer = new DataOutputStream(clientgetOutputStream());
while(true){
cmd = readerreadUTF();
Systemoutprintln(cmd);
if(cmdequals("getfilelist")){
fileArrayclear();
//fileArray = getFile(new File("D:/tmp"));
fileArray = getFile(new File("D:/学习/教程/学习笔记"));
String fn = "";
for(int k = 0; k < fileArraysize(); k ++){
fn = fileArrayget(k)getName();
writerwriteUTF(fn);
writerflush();
}
writerwriteUTF("");
}
if(cmdstartsWith("getfilecontent_")){
int i = IntegerparseInt(cmdsplit("_")[1]);
File f = fileArrayget(i);
Reader in = new InputStreamReader(new FileInputStream(f));
int tempbyte;
String str = "";
            while ((tempbyte = inread()) != -1) {
             str += (char)tempbyte;
             //Systemoutprintln(str);
            }
            inclose();
                writerwriteUTF(str);
}
}

} catch (IOException e) {
eprintStackTrace();
}
}
private static ArrayList<File> getFile(File f) {
File[] ff = flistFiles();
for (File child : ff) {
if (childisDirectory()) {
getFile(child);
} else {
fileArrayadd(child);
}
}
return fileArray;
}
}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/12575093.html

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

发表评论

登录后才能评论

评论列表(0条)

保存