Java小项目点餐系统(二)之服务端

服务端详解:

服务端的主要功能就是无限监听一个端口号,对客户端发来的连接请求给予回应,然后开辟新线程处理客户端。界面做的比较简单就是显示在线的用户,分为商家和学生。

一.监听客户端的socket连接请求

<span style="font-family:KaiTi_GB2312;font-size:18px;">package mainjframe;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.LinkedList;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class MainWindow extends JFrame{
	ServerSocket server;
	JTable user_table;
	JTable seller_table;
	JScrollPane user_jscrollPane;
	JScrollPane seller_jscrollPane;
	DefaultTableModel user_model;
	DefaultTableModel seller_model;
	String []user_headers = {"序号","在线学生"};
	String []seller_headers = {"序号","在线商家"};
	Object [][]cellData=null;
	LinkedList<User> student,seller;
	LinkedList<Socket> mysocket;

	public static void main(String args[])
	{
		new MainWindow("服务端");
	}
	public MainWindow(String s)
	{
		super(s);
		student = new LinkedList<User>();
		seller = new LinkedList<User>();
		mysocket = new LinkedList<Socket>();
		addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				dispose();
				System.exit(0);
			}
		}
		);
		//获取屏幕大小
	    Dimension screenSize =Toolkit.getDefaultToolkit().getScreenSize();
	    //设置窗体的位置和大小
	    setBounds((screenSize.width-320)/2,(screenSize.height-240)/2,320,240);
	    setLayout(new GridLayout());
	    user_model = new DefaultTableModel(cellData,user_headers);
	    user_table = new JTable(user_model);
	    seller_model = new DefaultTableModel(cellData,seller_headers);
	    seller_table = new JTable(seller_model);
	    user_jscrollPane = new JScrollPane(user_table);
		user_jscrollPane.setPreferredSize(new Dimension(160, 240));
		seller_jscrollPane = new JScrollPane(seller_table);
		seller_jscrollPane.setPreferredSize(new Dimension(160, 240));
		add(user_jscrollPane);
		add(seller_jscrollPane);
		setVisible(true);
		validate();
		startServer();
	}
	void update()
	{
		user_model.setRowCount(0);
		seller_model.setRowCount(0);
		for(int i=0;i<student.size();i++)
		{
			user_model.addRow(new Object[]{i+1,student.get(i).account});
		}
		for(int i=0;i<seller.size();i++)
		{
			seller_model.addRow(new Object[]{i+1,seller.get(i).account});
		}

	}
	void startServer() {
        int i = 0;
        try {
        	//设置监听端口号和最大接入数
            server = new ServerSocket(8889, 3);
            System.out.println("==========start===========快点来啊");
            new Thread(new ListenThread(this)).start();
            while (true) {
                Socket socket = server.accept();
                mysocket.add(socket);
                i++;
                System.out.println("第" + i + "个用户连接成功!");
                System.out.println("该用户端的地址信息为:"+socket.getInetAddress());
                new Thread(new ServerThread(socket,this)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
class ListenThread implements Runnable
{
	private MainWindow mainWindow;
	public ListenThread(MainWindow mainWindow)
	{
		this.mainWindow = mainWindow;
	}
	public void run()
	{
		while(true)
		{
		for(int i=0;i<mainWindow.mysocket.size();i++)
		{
			if(mainWindow.mysocket.get(i).isClosed())
			{
						for(int j=0;j<mainWindow.student.size();j++)
						{
							if(mainWindow.student.get(i).address == mainWindow.mysocket.get(i).getInetAddress())
								mainWindow.student.remove(mainWindow.student.get(i));
						}
						for(int j=0;j<mainWindow.seller.size();j++)
						{
							if(mainWindow.seller.get(i).address == mainWindow.mysocket.get(i).getInetAddress())
								mainWindow.seller.remove(mainWindow.seller.get(i));
						}
						mainWindow.update();
						mainWindow.mysocket.remove(mainWindow.mysocket.get(i));
						System.out.println("客户端已经断开");
					}
			}

		try
		{
			Thread.sleep(500);
		}
		catch(Exception e)
		{}
	}}
}

</span>

在进程中使用while循环不断监听客户端发过来的请求,一旦请求建立成功就新建一个ServerThread子线程来处理客户端的请求,而主线程继续等待。同时开辟一个ListenThread线程不断判断哪一个线程已经断开连接。

二.在ServerThread中对客户端的请求进行处理

<span style="font-family:KaiTi_GB2312;font-size:18px;">package mainjframe;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class ServerThread implements Runnable {  

    private Socket socket;
    private String accept;
    String account,passwd;
    DataInputStream in = null;
    DataOutputStream out = null;
    LinkMySql linkMySql;
    String dept;
    private MainWindow mainWindow;
	// 创建静态全局变量

    public ServerThread(Socket socket,MainWindow mainWindow)
    {
    	this.mainWindow = mainWindow;
        this.socket = socket;
        linkMySql = new LinkMySql(this);
    }  

    // 任务是为一个用户提供服务
    @Override
    public void run()
    {
        try
        {
            // 读取客户端传过来信息的DataInputStream
        	in = new DataInputStream(socket.getInputStream());
            // 向客户端发送信息的DataOutputStream
            out = new DataOutputStream(socket.getOutputStream());
            System.out.println("放马过来吧!!!!");
            // 读取来自客户端的信息
            accept = in.readUTF();
            System.out.println(accept);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        if(accept.equals("LOGIN"))
        {
            try
            {
                  account = in.readUTF();
                  		passwd = in.readUTF();
                 System.out.println("用户名:"+account+"\n密码:"+passwd);
                 for(int i=0;i<mainWindow.student.size();i++)
                 {
                	 if(account.equals(mainWindow.student.get(i).account))
                	{
                		 socket.close();
                	}
                 }
                 for(int i=0;i<mainWindow.seller.size();i++)
                 {
                	 if(account.equals(mainWindow.seller.get(i).account))
                	{
                		 socket.close();
                	}
                 }
                 dept = linkMySql.query(account,passwd);
                 out.writeUTF(dept);
                 if(dept.equals("student"))
                 {
                	 User temp = new User();
                	 temp.account = account;
                	 temp.passwd = passwd;
                	 temp.type = "student";
                	 temp.address = socket.getInetAddress();
                	 mainWindow.student.add(temp);
                	 mainWindow.update();
                	 linkMySql.initStudent(in,out);
                	 linkMySql.handleOrder();

                 }
                 else if(dept.equals("seller"))
                 {
                	 User temp = new User();
                	 temp.account = account;
                	 temp.passwd = passwd;
                	 temp.type = "seller";
                	 temp.address = socket.getInetAddress();
                	 mainWindow.seller.add(temp);
                	 mainWindow.update();
                	 linkMySql.initseller(in,out);
                 }
            }
            catch(IOException e)
            {
            }
        }
        else if(accept.equals("REGISTER"))
        {

        }
    }
}  </span>

先读取客户端发来的请求,然后进入对应的功能模块,如果是用户登录,则进行sql语句操作并对结果做出反应,如果查询错误则关闭该线程,判断为学生则加入学生链表并初始化学生端的商品信息和店铺信息,判断为商家则把改商家的商品信息发过去并查找相应的订单表,把属于该商家的订单发给商家。

服务端的主要功能就是利用socket和多线程把学生端和商家端连接起来,并把所有对数据的操作集中在服务端来做,全部由服务端与数据库进行交互,保证数据的安全。

时间: 2024-08-08 13:45:30

Java小项目点餐系统(二)之服务端的相关文章

[Java]命令行模拟TCP客户端与服务端的简单小程序遇到的问题(基础不牢!扎实和亲手实践比什么都重要!)

简单得不能再简单的需求: 简单模拟TCP客户端与服务端的一次连接和通信,客户端发出一个消息,服务端回馈一个消息 自己第一次编写的代码: Client: class TcpClient1 { public static void main(String[] args) throws Exception { Socket s=new Socket("127.0.0.1",10010); OutputStream out=s.getOutputStream(); out.write(&quo

Android版网络办公系统应用客户端+服务端

该项目源码是Android版网络办公系统应用客户端+服务端,也是一个简单的网上办公系统的Android客户端,项目有服务端和客户端部分的源码的,客户端开发环境eclipse  AVD版本 4.0服务器 phpStudy 2013集成环境 Apache+php5.3+ISAPI模式 phpStudy 2013集成环境绿色版下载http://www.phpstudy.net/phpstudy/phpStudy2013d.zip官网   http://www.phpstudy.net/ android

【转-整理】Java 对外接口开发(http)服务端-客户端

java开发接口利用http协议传输数据 这个接口主要用来登录,java服务器提供一个接口,移动设备客户端(android和ios)能通过这个接口把用户名和密码之类的东东传过来到服务器验证,然后服务器返回数据告诉客户端是否登录成功.比如0是成功,1是失败.中间数据的传递都是通过http协议完成.这个接口该怎么写? 代码1.2为服务器接口,接收到客户端的信息解析验证,并返回需要的信息. 服务端代码: 1 public class TestTransfers extends HttpServlet

基于thrift的java和python分别作为客户端和服务端的调用实现

前面已经实现了纯java的thrift的实现. 现在实现实现一下python作为客户端和服务端的thrift的调用 1.python作为客户端,java作为服务端 java服务端代码参考前面写的博客 客户端python的准备: 1.使用mac下的PyCharm,专业的python开发工具 2.生成python代码 thrift --gen py thrift/data.thrift 3.在mac下安装thrift的python依赖 sudo python setup.py install 安装t

搭建nfs共享存储服务之二nfs服务端配置语法及配置实战详解

1.1.NFS服务端配置文件路径为: /etc/exports,并且默认为空,需要用户自行配置. /etc/exports文件配置格式为: NFS共享的目录 NFS客户端地址1(参数1,参数2...)客户端地址2(参数1,参数2) 1.NFS共享的目录:为NFS服务端要共享的实际目录,要用绝对路径,如(/data),注意共享目录的本地权限,如果需要读写共享,一点要让本地目录可以被NFS客户端的用户(nfsnobody)读写. 2.NFS客户端地址:为NFS服务端授权的可访共享目录的NFS客户端地

java socket 多线程通讯 使用mina作为服务端

客户端代码不变,参照 http://www.cnblogs.com/Westfalen/p/6251473.html 服务端代码如下: import java.io.IOException; import java.net.InetSocketAddress; import org.apache.mina.core.service.IoHandlerAdapter; import org.apache.mina.core.session.IdleStatus; import org.apache

java的客户端可以连接CPlus的服务端

今天做的实验,用c++做的服务端,端口号为6000:用java做的客户端,IP为127.0.0.1,port为6000,结果双方可以连接上线: 贴代码: 服务端: #include <winsock2.h>#include <iostream>using namespace std;SOCKET sockConn = NULL;char content[100] = " ";int flag = 1;DWORD WINAPI MYrevc(LPVOID lp){

android菜鸟学习笔记25----与服务器端交互(二)解析服务端返回的json数据及使用一个开源组件请求服务端数据

补充:关于PHP服务端可能出现的问题: 如果你刚好也像我一样,用php实现的服务端程序,采用的是apache服务器,那么虚拟主机的配置可能会影响到android应用的调试!! 在android应用中访问的IP都是10.0.2.2,如果在apache虚拟主机配置文件中配置了多个虚拟主机,那么将默认解析为对第一个虚拟主机的请求,所以,在调试android应用时,应该将对应的服务端所配置的那个虚拟主机放在配置文件中的第一个虚拟主机的位置.否则就会出现请求的文件不存在等的错误. 服务端返回JSON数据及

java网络编程TCP传输—流操作—服务端反馈与客户端接收

在读取完流后,服务端会向客户端返回一些数据,告诉客户端,已经写完了. 在这里和”流操作—拿到源后的写入动作“差不多,客户端同样以byte与Buffered两种缓冲读取作为例子,同时,.也是希望大家给补充. 1.利用OutputStream向客户端回写,客户端用byte作为缓冲接收 向客户端回写: 1 //获取socket输出流,将上传成功字样传给客户端 2 OutputStream out=s.getOutputStream(); 3 out.write("上传成功".getBytes