1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > java 仿qq 传文件_java网络编程实现QQ发消息文件 图片等内容

java 仿qq 传文件_java网络编程实现QQ发消息文件 图片等内容

时间:2019-08-17 11:26:54

相关推荐

java 仿qq 传文件_java网络编程实现QQ发消息文件 图片等内容

前言:昨天我们已经初步学习了网络编程到底是怎么一回事儿,今天在此基础上继续学习网络编程,利用网络编程实现 QQ上的发送消息,群聊,私聊等功能。

首先我们来回顾一下昨天的两点基础知识:

1、建立服务器端

服务器建立通信ServerSocket

服务器建立Socket接收客户端连接

建立IO输入流读取客户端发送的数据

建立IO输出流向客户端发送数据消息

2、建立客户端

创建Socket通信,设置通信服务器的IP和Port

建立IO输出流向服务器发送数据消息

建立IO输入流读取服务器发送来的数据消息

群聊思路分析:

首先我们都知道,群聊是什么形式的,群聊就是一个人发的消息,所有人都可见,但是这要在程序中怎样体现这种关系呢?

首先我们必须明确知道的是,客户端只能向服务器端发送内容,服务器端只能接受客户端发送来的数据,客户端的其他需求可以在发送的字符里面体现。因为QQ的聊天中,分私聊和群聊,所以服务器端就要区分什么内容是群聊什么是私聊,谁私聊谁,为了解决这些问题,我们必须给客户端和服务器端一个统一的规范,这个统一的规范是让服务器端知道发送的是群聊消息还是私聊消息,谁私聊谁的问题。

下面我们定义的规范如下:

例如:p+ wll♥ 晚上好 p+——>服务器译为:私聊wll发送的内容是晚上好

a+ 大家好 a+——> 译为:是群发消息,发送的内容是:大家好

下面我们new一个interface,存放这些规范,如下所示:

//定义一套规范

public interface Chatinterface {

//登录

String LOGIN_FLAG = "u+";

//私聊

String PRIVATE_FLAG="P+";

//群聊

String PUBLIC_FLAG = "a+";

// 分隔符

String SPLTI_FLAG = "♥";

// 成功

String SUCCESS = "1";

//失败

String FAILE = "-1";

}

根据昨天学习的知识,我们知道要定义服务器端和客户端,但是谁来管理登录,私聊群聊呢?所以这里我们要定义一个类来管理。

以下我们定义一个UserManager类来管理,相关注释如下所示:

public class UseraManager {

//保存所有用户的信息

private Map users = new HashMap<>();

//判断银狐是否已经登录

public boolean isLogined(String name) {

//遍历数组

for (String key : users.keySet()) {

if (key.equals(name)) {

return true;

}

}

return false;

}

//保存当前登录的用户信息

public void save(String name, Socket socket) {

users.put(name, socket);

}

//通过用户名找到对应的socket

public Socket socketName(String name) {

return users.get(name);

}

//通过socket找到对应的名称

public String nameBySocket(Socket socket) {

for (String key : users.keySet()) {

//取出这个key对应的socket

if (socket == users.get(key)) {

return key;

}

}

return null;

}

//获取所有人的socket

public synchronized Collection allUsers (){

return users.values();

}

}

`2.建立客户端:

我们知道客户端首先要做的就是建议socket,然后向服务器端发送数据和接收服务器端的数据。第一步:new一个Client类,第二步:创建socket,第三步:创建发送和接收的数据流,格式如下:

//1.创建用于通信的socket

// 指明和谁通信:ip地址 端口号

Socket socket = new Socket("192.168.43.32",8989);

//2. 接收服务器端的数据

BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

//3.读取服务器端发来的数据

String line = null;

while ((line = br.readLine()) != null){

System.out.println(line);

}

3,多线程,不管是服务器端还是客户端都要接受数据和发送数据,但早发送数据的同时使可以接受数据的,早接收数据的同时,也是可以发送数据的,所以在客户端和服务器端都要使用多线程,服务器端的子线程用来处理客户端发送来的数据:判断是否已经登录,判断是群聊还是私聊,判断私聊给谁,

1.判断是否已经登录如下:

判断用户名是否已经登录

if(Server.manager.isLogined(name)){

//登录过了

ps.println(Chatinterface.FAILE);

} else {

//没有登录过

Server.manager.save(name,socket);

ps.println(Chatinterface.SUCCESS);

}

}

2.判断是不是私聊:

//判断是不是私聊

else if(line.startsWith(Chatinterface.PRIVATE_FLAG)&&line.endsWith(Chatinterface.PRIVATE_FLAG)){

//用户名和聊天内容

//获取信息

int len =line.length()-2;

String msg = line.substring(2,len);

//分割

String[] itens = msg.split(Chatinterface.SPLTI_FLAG) ;

String name = itens[0];

String massage = itens[1];

//通过用户名找到对应的socket

Socket destsocket = Server.manager.socketName(name);

PrintStream desPS = new PrintStream(destsocket.getOutputStream());

//获取当前用户的名称

String currentName = Server.manager.nameBySocket(socket);

//发的送私聊信息

desPS.println(currentName +"想你发来私聊"+massage);

}

因为经过第一步,说明已经登录,经过第二步:说明不是群聊,所以就只用私聊了,处理私聊的大妈如下:

int len =line.length()-2;

String msg = line.substring(2,len);

String currentNmae = Server.manager.nameBySocket(socket);

//遍历所有的用户信息

Collection sockets = Server.manager.allUsers();

for(Socket s :sockets){

PrintStream temps = new PrintStream(s.getOutputStream());

temps.println(currentNmae+"发来群聊"+msg);

}

整个代码如下:

客服端:

public class Client {

public static void main(String[] args ){

//BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

BufferedReader br = null;

PrintStream ps = null;

BufferedReader bufferedReader = null;

try ( Socket socket = new Socket("192.168.43.32",8898);){

br = new BufferedReader(new InputStreamReader(System.in));

ps= new PrintStream(socket.getOutputStream());

bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));

while (true){

//接受终端输入信息

String line = JOptionPane .showInputDialog("请登录");

// String line = br.readLine();

//拼接登录格式

String loginStr = Chatinterface.LOGIN_FLAG+line+Chatinterface.LOGIN_FLAG;

//发送给服务器

ps.println(loginStr);

//接受服务器端返回的结果

String result = bufferedReader.readLine();

if(result.equals(Chatinterface.SUCCESS)){

System.out.println("登录成功");

break;

}else {

System.out.println("用户已存在,请重新登录");

}

}

//登录成功

//发送数据,接受数据

//开启线程处理服务器端的输入

new ClientThread(socket).start();

String line ;

while ((line = br.readLine())!=null){

ps.println(line);

}

} catch (IOException e) {

}

}

}

子线程:

class ClientThread extends Thread{

private Socket socket ;

public ClientThread(Socket socket ){

this.socket = socket;

}

@Override

public void run() {

BufferedReader br = null;

try{

br= new BufferedReader(new InputStreamReader(socket.getInputStream()));

String line = null;

while ((line = br.readLine())!=null){

System.out.println(line);

}

} catch (IOException e) {

System.out.println("网络出错");

}finally {

try {

if (br != null) {

br.close();

}

if(socket != null){

socket.close();

}

}catch (IOException e) {

}

}

}

}

服务器端:

public class Server {

//用于保存每个与用户姓名和socket

public static UseraManager manager = new UseraManager();

public static void main(String[] args){

try( ServerSocket ss = new ServerSocket(8898);) {

while (true) {

Socket socket = ss.accept();

//让子线程处理这个Socket

new ServerThread(socket).start();

}

} catch (IOException e) {

}

}

}

服务器端子线程:

class ServerThread extends Thread{

private Socket socket;

public ServerThread (Socket socket){

this.socket = socket;

}

@Override

public void run() {

BufferedReader br= null;

PrintStream ps = null;

//登录

//1.获取输入流

try {

br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

ps= new PrintStream(socket.getOutputStream() );

String line =null;

while ((line = br.readLine()) !=null){

if(line.startsWith(Chatinterface.LOGIN_FLAG)&&(line.endsWith(Chatinterface.LOGIN_FLAG))){

// String [] items= line.substring(2).split("u+");

// String name =items[0];

String name = line.substring(2,line.length()-3);

//判断用户名是否已经登录

if(Server.manager.isLogined(name)){

//登录过了

ps.println(Chatinterface.FAILE);

} else {

//没有登录过

Server.manager.save(name,socket);

ps.println(Chatinterface.SUCCESS);

}

}

//判断是不是私聊

else if(line.startsWith(Chatinterface.PRIVATE_FLAG)&&line.endsWith(Chatinterface.PRIVATE_FLAG)){

//用户名和聊天内容

//获取信息

int len =line.length()-2;

String msg = line.substring(2,len);

//分割

String[] itens = msg.split(Chatinterface.SPLTI_FLAG) ;

String name = itens[0];

String massage = itens[1];

//通过用户名找到对应的socket

Socket destsocket = Server.manager.socketName(name);

PrintStream desPS = new PrintStream(destsocket.getOutputStream());

//获取当前用户的名称

String currentName = Server.manager.nameBySocket(socket);

//发的送私聊信息

desPS.println(currentName +"想你发来私聊"+massage);

}else{

int len =line.length()-2;

String msg = line.substring(2,len);

String currentNmae = Server.manager.nameBySocket(socket);

//遍历所有的用户信息

Collection sockets = Server.manager.allUsers();

for(Socket s :sockets){

PrintStream temps = new PrintStream(s.getOutputStream());

temps.println(currentNmae+"发来群聊"+msg);

}

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

运行结果:

总结:只是点开始综合了,但是逻辑还是简单的,前面的基础只是有点遗忘的,现在的去看看前面的,有种感觉就是,学习一个只是点的时候不知道他的具体作用,到真正的实战中才能知道对这个只是点到底了解多少,还需要继续努力。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。