发顺丰一步步实现聊天室,从建立简单服务器开始~
本章内容:
1:预备知识(网络基础、通讯)
2:建立简单服务器
实现服务器的读写消息功能
1、预备知识
我们每天都在使用QQ微信等通讯工具,当我们在消息框输入消息点击发送键之后,消息就会出现在对方的消息框中,这是如何实现的呢?如下图所示:
我们知道每台设备都有自己的一个ip地址,以便另一台设备能够找到它,两台通信设备之间的通信,实际上是两台通信设备上的程序之间的通信,所以找到通讯设备之后还需要找到设备上对应的程序。就好比你找一个跟你住在不同楼栋的同学的位置(假设这个同学正待在他的寝室),仅仅知道他住在第几栋还不够,你还需要知道具体的寝室号,这个寝室号就是我们接下来说的端口的概念,端口号用来标识需要通讯具体的应用程序。
每一台机器都有从 0~65535个端口号,其中的每一个数字,可供一个程序通信用,通常情况下0~1024 的端口要尽量避免使用—我们称它为知名端口,例如打开网页时,则连结上的是服务器上的80 端口,在地址栏不需要输入这个端口号,是因为它是默认的;我们在设置自己服务器的端口号时,要确保这个端口号没有被占用,所以也尽量避免使用80、8080这样的端口号。
找到自己的ip,在命令提示符窗口输入ipconfig: IPv4地址对应的就是当前的本机的IP地址,试一下在不同的地方ipconfig一下,看看是否有不同~
(win10版本的右键点击开始按钮,找到命令提示符。)
有几个常用的命令提示符,感兴趣的可以百度一下
ipconfig、ping、statnet:、telnet(后面会用到)(windows的一个应用程序,之前没有启动过的需要手动启动一下,打开控制面板–>查看方式 大图标–>程序与功能–>左边启动或关闭Windows功能–>勾选有关Telnet的功能):
想知道更多也可以 直接在命令提示符框中: (命令提示符) help 回车
2、建立简单的服务器 、实现简单的读取发送消息的功能
建立简单服务器需要用到的API:
ServerSocket(服务器)、Socket(客户机对象)、输入输出流相关的InputStream、OutputStream等等、线程Thread、..
实现思路:
1、根据指定的端口实例化ServerSocket服务器对象
2、实例化Socket对象,让服务器进入等待客户机的状态(此时如果没有客户机连接,服务器将会进入阻塞状态,不会继续执行接下来的程序语句)
3、实例化输入输出流,从客户机中得到
4、发送和读取消息(要明确一定的规则确定消息的起止)
5、明确聊天结束后关闭输入输出流,关闭客户机。
这个过程好比:
1:到电信注册一个手机号码
2、注册号码后没有电话打进时,手机一直处于待机等待状态
3、打电话要与对方建立一个消息传递的管道,输入流相当于听筒,输出流相当于喇叭,对方的消息要从听筒获取,自己的消息要通过输出流发送
4、我们说的话是一个一个字组成,输入输出流传递的是一个一个字节,在我们说话的过程当中,停顿代表着一句话的停顿,同样也要明确一定的规则规定输入输出流传递的字节,比如回车换行符代表一句话的结束
5、我们通话的时候说出再见、下次再聊这样的话来与对方说明通话的结束,同样也要规定一定的规则,当服务器读到这种结束的标志时再关闭与客户机建立联系的管道。不然就类似于出现无缘无故挂电话,或者明明通话结束没有挂机的情景。
好,完整代码奉上:
public class ChatServer {
/**
* 在指定端口上启动一个服务器
* @param port: 服务器所以的端口
*/
public void setUpServer(int port){
try{
// 建立绑定在指定端口上的服务器对象
ServerSocket server=new ServerSocket(port);
System.out.println(" 服务器创建成功! "+port);
// 让服务器进入等待状态 : 阻塞状态
Socket client=server.accept();
// 从连结对象上得到输入输出流对象
OutputStream out=client.getOutputStream();
InputStream ins=client.getInputStream();
String s=" 你好 , 欢迎来 javaKe.com\r\n";
byte[] data=s.getBytes();// 取得组成这个字符串的字节
out.write(data); // 用输出对象发送数据!
out.flush();// 强制输出
client.close();// 半闭与客户机的连结
}catch(Exception ef){
ef.printStackTrace();
}
}
// 主函数
public static void main(String[] args) {
ChatServer cs=new ChatServer();
cs.setUpServer(9090);
}
}
接下来实验一下,服务器有没有创建成功吧~
打开命令提示符框,输入telnet命令 IP地址(localhost代表本机) 端口号
其实这时候这个黑框框就相当于一个客户机去连接我们创建的服务器啦~
如果连接成功就会收到服务器发送的消息,回车后就结束了跟服务器的连接
可能我们写好的服务器会有这样的错误:这是因为端口已经被占用啦,注意在调试程序时不要同时启动多次。现在服务器能发送一句话,接下来实现客户机和服务器的多轮对话:
将read方法和write方法放到循环当中,当服务器没有读取到bye的时候循环收发消息
// 客户机与服务器连接的方法
public void processChat(java.net.Socket client) {
// 根据客户机实例化输入输出流
try {
OutputStream os = client.getOutputStream();
InputStream is = client.getInputStream();
String s = "你好,欢迎来到服务器!*";
// 输入输出是根据字节 ,将字符串转换为字节
byte[] b = s.getBytes();
os.write(b);
os.flush();// 强制输出
// 用读取字符串的方法,从输入流中读取一个字符串
String inputS = readString(is);
while (!inputS.equals("bye")) {
b = s.getBytes();// 取得组成这个字符串的字节
os.write(b);// 用输出对象发送
os.flush();// 强制输出
inputS = readString(is);// 读取客户机的下一个句子
}
s = "您好,欢迎再来!\r\n";
b = s.getBytes();
os.write(b);
os.flush();
client.close();// 关闭与客户机的连接
} catch (Exception ef) {
ef.printStackTrace();
}
}
/**
* 读取字符串的方法 从输入流对象中读取字节,拼成一个字符串返回 如果读到的一个字节值为13,则认为以前的是一个字符串
*
* @param ins
* 输入流对象
* @return 从流上(客户机发来的)读到的字符串
*
*
*/
public String readString(InputStream is) throws Exception {
// 创建一个字符串缓冲区
StringBuffer sb = new StringBuffer();
char c = (char)is.read();
while (c != *) {
// 遇到一个换行,就是一句话
sb.append(c);
int i = is.read();// 读取客户机发来的一个字节
c = (char) i;// 将输入的字节转换为一个char
}
// 将读到的字节转换为字符串,并调用trim去掉尾部的空格,系统会默认添加的一定要加上trim方法
String inputS = sb.toString().trim();
System.out.println("inputS "+inputS );
return inputS;
}
写代码的时候注意封装性,尽量把实现不同功能的代码封装到不同的方法当中,再去调用方法。
实例化Socket对象之后就调用这里的process方法~
由于这里是一个一个字节读取,所以中文会出现乱码的情况,因为中文字符是占两个字节,一个一个字节读?半个汉字。。?
所以我们可以改进一下,用Bufferedreader的readline方法来一行一行读取
实例化BufferedReader对象
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
String msg = br.readLine();
while (!msg.equals("bye")) {
msg = br.readLine();
//读取下一句
}
好了~现在客户机和服务器一对一的消息传递基本可以实现,那多个客户机连接呢?
下一篇继续完善我们的聊天室~
希望有人能看到戳小编多多交流~
声明:本文部分素材转载自互联网,如有侵权立即删除 。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
丞旭猿论坛
暂无评论内容