`
fddong123456
  • 浏览: 6636 次
社区版块
存档分类
最新评论

根据通信协议做一个简单的聊天对话的个人设计思路

    博客分类:
  • java
阅读更多

一、通信中包含的主要内容:

                              客户端                                  服务器

连接服务器:

Socket cilent = new Socket(IP地址,服务器设置的端口号);

监听服务器端口:

ServerSocket ss = new ServerSocket(设置端口号);

接收客户端的连接:

Socket socket = ss.accept;

InputStream input = cilent.getInputStream;

read()方法读取服务器发送过来的信息。

OutputStream output = socket.getOutoutStream;

write()方法往客户端发送信息。

OutputStream output = cilent.getOutoutStream;

write()方法往服务器发送信息。

InputStream input = socket.getInputStream;

read()方法读取客户端发送过来的信息。

注意:1、服务器和客户端要分开设计,最好是各建一个工程。

           2、读read和写write都是通过字节的形式完成的(自己还可重新定义读和写的方法)。

           3、写入和读取的顺序不要混淆。

 

二、主要设计思路:

1、首先是编写一个简单的服务器。

      (1)、先建一个带有主函数的类MyServer,在这个类中实现一个myServer方法,该方法中用于创建监

                   听端口的套接字ServerSocket对象,并接受客户端Socket的访问,例如:

                  

public void setServer(int port){		
		try {
			//创建ServerSocket套接字对象用于监听port端口
			ServerSocket ss = new ServerSocket(port);
			System.out.println("服务器等待客户端的访问");
			//等待接受客户端的访问,如果没有客户端的访问,就在这停止等待客户端的访问
			Socket socket = ss.accept();
			System.out.println("已连有客户接服务器");		
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

    再主函数中调用该方法,然后就可以通过(程序---运行---cmd---telnet  ip地址  端口号)访问这个简单

    服务器,此时只可以访问这个服务器,还不可以与服务器进行交流。

 

    (2)、如果要进行交流,就要有输入输出流进行读写信息

                 InputStream input = socket.getInputStream;

                 outputStream output = socket.getOutputStream;

                 需注意:读和写都是通过字节的形式完成的。自己定义写入和读取的规则

                

     (3)、如果要服务器接受多个客户端,就要把接受访问的Socket的对象放到一个死循环中,这样服务器

                  就一直处于等待接受状态。例如:

       

	while(true){
				System.out.println("服务器等待客户端的访问");
				//循环等待接受客户端的访问,如果没有客户端的访问,循环就在这停止等待客户端的访问
				Socket socket = ss.accept();
				System.out.println("已连有客户接服务器");
				//创建ServerThread线程对象,把客户端的连接放到线程里处理,并启动线程
				ServerThread st = new ServerThread(socket);
				st.start();
				
			}

 

     (4)、然后添加一个线程,把Socket对象接收到的连接放到这个线程中处理,再添加一个死循环,让服

                 务器一直处于发送和读取信息状态。例如:

    

        public ServerThread(Socket scoket){
		this.scoket = scoket;
	}
	
	public void run(){
		try {
			InputStream input = scoket.getInputStream();
			OutputStream output = scoket.getOutputStream();
			
			String str = "sdfadfad";
			byte[] bytes = str.getBytes("GB2312");
			
			output.write(bytes);
			
			
		//接受客户端信息
		while(true){
				//从客户端读取一个字节
				String str1 = readLine(input);
				System.out.println(str1);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
	}

 

2、编写一个客户端。

               一个简单的客户端只要可以发送和接受消息,并在界面上显示出来就可以了。设置一个简单的聊天

       界面,界面上有两个文本区(一个用于往服务器发送消息,一个用于显示从服务器接收到的消息)和一

       个发送按钮,并且给按钮添加事件监听器。

                界面完成后,首先要把客户端与服务器建立连接,这就要创建Socket对象,要发送和接收到消息

       就要创建输入输出流对象,例如:

               Socket cilent = new Socket(192.0.0.133(IP地址),8888(这里要填写服务器设置的端口号));

               输入流  InputStream input = cilent.getInputStream;

               输出流   OutputStream output = cilent.getOutputStream;     

               然后就可以获取文本区中输入的内容及按钮对象,往服务器发送消息(输出流的write()方法)和接

        受消息(输入流的read()方法)。例如:

     

//得到在第二个文本框中输入的内容
		String cmd = jtf1.getText();
		try {
				output.write((cmd+"#").getBytes());   //往服务器发送一条信息	
		                  //从服务器读取一条信息
				String msg = readLine(input);
                                //将读取的信息在第一个文本框中显示出来
				jtf.append(msg+"\n");
		} catch (IOException e1) {
			e1.printStackTrace();
		}

 

3、添加新的功能,完善服务器和客户端。

        (1)、给客户端添加登录界面。

                         首先设置登录界面,登录界面包含账号输入框和密码输入框,还有登录和注册按钮。客户端

                  把Socket对象以及输入输出流对象设置在登录界面的事件监听器类里面,其它地方需要时,可以

                  通过构造方法或get方法把它们传过去。在服务器端把读取的账号和密码验证是否存在之前,自己

                  先定义一些账号和密码,并进行初始化存到集合框架中(例如:哈希表),然后验证,并把验证

                  结果返还给客户端,并作相应的处理。

                 在服务器中验证账号和密码:

           

    //判断账号和密码是否正确
     if(passWord.equals(map.get(userName))&&eqUser()){					
        msg = "服务器登录成功#";
	System.out.println(msg);
	output.write(msg.getBytes());					
    }else if(passWord.equals(map.get(userName))&&!eqUser()){
	msg = "账号已经登录#";
	System.out.println(msg);
	output.write(msg.getBytes()); 
    }else{
	msg = "账号或密码输入不正确,请重新输入 #";
	output.write(msg.getBytes());
	System.out.println(msg);
   }

 

        (2)、给客户端添加注册功能。

                        首先设置注册界面,登录界面包含账号输入框、密码输入框和密码重新输入框,还有确定和

                 取消按钮。先通过构造方法把输入输出流对象传过来,先验证两次输入的密码是否正确,若正

                 确,把账号和密码发送给服务器,验证该账号是否存在,若不存在,直接把账号和密码存到哈希

                 表中或存到一个文件中,若存在,返还一条信息给客户端。

          在服务器中验证注册的账号和密码:

         

//读取注册的账号
String suer = readLine(input);					
//读取注册的密码
String spass = readLine(input);
//初始化一个布尔类型的变量,用于标示注册的用户是否存在,true表示注册的用户不存在,false表示注册的用户存在
boolean Flag = true;
Set<String> set = map.keySet();    //创建Set对象,并获取哈希表中的用户名集合,Set中存的内容是无序的且不可重复的
Iterator<String> iter = set.iterator();  // 创建迭代对象,
while(iter.hasNext()){
	String key = iter.next();
	if(suer!=null&&suer.equals(key)){
		//往客户端写入内容
		String msg = "此账号已存在,请重新注册#";
		System.out.println(msg);
		output.write(msg.getBytes());
		Flag = false;
		break;
	}
}
					
if(Flag == true){
	//往客户端写入内容
	String msg = "注册成功#";
	output.write(msg.getBytes());
	//往文件里写注册的账号和密码
	FileOutputStream fos = new FileOutputStream("D:/Users/Adminstrator/workspace/通信服务器0826/src/com/fuwuduan/cunchu",true);
	//往文件里写账号和密码
	fos.write("账号: ".getBytes());
	fos.write((suer+" , ").getBytes());
	fos.write("密码: ".getBytes());
	fos.write((spass+"\n ").getBytes());
							
	fos.close();
}

 

 

        (3)、客户端与客户端能够实现群聊。

                         在服务器端创建一个数组队列(或其它集合框架),把每个接收到访问的Socket的对象或

                  Socket对象的线程存到队列中,发送消息时,遍历队列,往每个客户发送消息。

                  群聊时直接调用群发的方法:

        /**
	 * 发送一条消息
	 */
	public void sendMsg(String msg){
		
		try {
			output.write(msg.getBytes());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 群发消息
	 * @param msg
	 */
	public void sendAllMsg(String msg){
		for(int i=0; i<MyServer.list.size(); i++){
			ServerThread st = MyServer.list.get(i);
			st.sendMsg(msg);
		}
	}

  

 

        (4)、客户端与客户端能够实现点对点聊天。

                  先向服务器发送往那一个客户发送消息,然后从队列中取出这个用户,并发送消息。例如:

msg = readLine(input);   //从客户端读取一行
for(int i=0; i<MyServer.list.size(); i++){
	if(MyServer.list.get(i).getUserName().equals(msg)){
		String msg1 = userName+"说:\n      "+readLine(input)+"#";
		sendMsg(msg1);   //往发出信息的客户端发送这条信息
		ServerThread sst = MyServer.list.get(i);
		sst.sendMsg(msg1);  //往要接受的用户发送信息
	}
}

   

 

分享到:
评论

相关推荐

    java源码包---java 源码 大量 实例

    一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源代码...

    JAVA上百实例源码以及开源项目源代码

    用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天通信演示代码 2个目标文件...

    java源码包2

    一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源...

    java源码包3

    一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源...

    java源码包4

    一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天通信演示代码 2个目标文件...

    JAVA上百实例源码以及开源项目

    一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源代码...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    用累加器,以对话状态存储起来,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除…… Java Socket 聊天通信演示代码 2个目标文件...

    Visual C++2010开发权威指南(共三部分).part1.rar

    第一部分 Visual C++ 2010开发与新特性 第1章 Visual C++ 2010开发环境简介 1 1.1 Visual C++ 2010简介 1 1.2 Visual C++ 2010下载安装指南 1 1.3 Visual C++ 2010主要特点与新特性 3 1.4 Visual C++ 2010开发环境...

Global site tag (gtag.js) - Google Analytics