Java——网络编程(实现基于命令行的多人聊天室)

目录:

1.ISO和TCP/IP分层模型

2.IP协议

3.TCP/UDP协议

4.基于TCP的网络编程

5.基于UDP的网络编程

6.基于TCP的多线程的聊天室的实现

1.ISO和TCP/IP分层模型

OSI分层模型(Open System Interconnection)为“开放系统互连参考模型”。为国际标准化组织ISO提出。

TCP/IP分层模型更和实际应用相贴近。

对应关系如上图。其中TCP/IP体系中,网络层对应IP(Internet Protocol),传输层对应TCP(Transmiss Control Protocl)。

**分层思想:**只有相邻的两层才能够进行信息的交互。如:应用层需要传输信息时,会将信息交给传输层,传输层会将信息进行包装,并传递给网络层;网络层会将信息再次包装,在传递给物理+数据链路层。而别的计算机需要解析信息时,也需要反向层层解析,才能获得应用所需的信息。

2.ip协议

负责提供独一无二的ip地址。

传送信息时除了需要ip地址,也需要**端口号。**ip地址相当于选择连接互联网上的某台计算机,而端口号相当于选择连接一台计算机上的某个应用。

端口号可以从0-65535,通常分三类:①公认端口:0-1023,http默认80端口;②注册端口:1024-49151,通常应用程序应该使用这个范围内的端口;③动态/私有端口:49152-65535,应用程序不会主动会用这些端口,一般是动态分配的。

端口号又分tcp和udp:比如tcp888和udp888是不一样的。

3.TCP/UDP协议:

tcp可靠但是慢(因为有确认):如银行登录。

udp不可靠但是快:如发qq语音,如果丢包也就是语音兹拉几声;cf网络问题导致闪现;

如果网络在不太挤的话,udp也比较可靠,如果挤则肯能被路由器丢失,这就是丢包。

Socket:

一般网络编程也称为socket编程。

关于网络编程的类一般都在java.net:其下有两个类一个socket(client),一个serversocket(server)分别用来实现双向链接的client端和server端

这都是对tcp而言,因为对于udp而言没有严格意义上的server和client。

建立连接时所需的寻址信息为远程计算机的ip地址端口号(Port number),ip地址相当于寻找计算机,而端口号寻找同一计算机上的不同应用程序。

4.基于TCP的网络编程:

ServerSocket是堵塞式的(accept方法是阻塞式的),因为有时有Client访问有时没有,所以SercerSocket不间断运行,等待Client连接。

Client和Server交流通过“流”。

readUTF也是阻塞式的。会导致其他client在阻塞期间连接不上。

代码如下:

1//TCPSevrver.java 2 3import java.io.DataInputStream; 4import java.io.InputStream; 5import java.net.*; 6 7public class TCPserver { 8 9 public static void main(String[] args) throws Exception { 10 11 ServerSocket ss=new ServerSocket(6666); 12 while(true) {//为了满足服务器不间断的条件 13 Socket s=ss.accept();//在server也建立一个socket,用来接收client来的申请 14 15 DataInputStream dis=new DataInputStream(s.getInputStream());//从输入流里获取数据 16 System.out.println(dis.readUTF());//打印数据 17 dis.close();//关闭输入流 18 s.close();//关闭Client的连接 19 } 20 } 21} 22 23//TCPClient.java 24 25import java.io.DataOutputStream; 26import java.io.OutputStream; 27import java.net.*; 28 29public class TCPclient { 30 public static void main(String[] args) throws Exception { 31 Socket s=new Socket("127.0.0.1", 6666);//创建连接Server的Socket,根据ip和端口 32 33 OutputStream os=s.getOutputStream(); 34 DataOutputStream dos=new DataOutputStream(os);//输出流 35 dos.writeUTF("hello server"); 36 37 dos.flush(); 38 dos.close();//关闭输出流 39 40 s.close();//关闭Client的连接 41 } 42}

5.基于UDP的网络编程

6.基于TCP的多线程的聊天室的实现

思想就是将Service和Client的交互都放入新的线程中。从而使数据交互不会堵塞。

实现共4个.java文件:

MyServer.java——服务器主体

ServerThread.java——服务器为处理单个Client创建的线程

MyClient.java——客户端主体

ClientThread.java——Client中实现等待服务器发送聊天内容的线程

直接贴代码:

1package TalkRoom; 2 3import java.io.IOException; 4import java.net.*; 5import java.util.*; 6 7public class MyServer { 8 9 //定义保存所有socket,并将其包装成线程安全的 10 public static List<Socket> list=Collections.synchronizedList(new ArrayList<>()); 11 12 public static void main(String[] args)throws IOException { 13 // TODO Auto-generated method stub 14 ServerSocket ss=new ServerSocket(8888); 15 //如果没有人连接,就一直堵塞 16 while(true) { 17 Socket s=ss.accept(); //将连接的client保存在s中 18 list.add(s);//将新的s添加进s的list中 19 20 //每当一个client连接到server,server总会开启一个新的线程与client进行服务 21 new Thread(new ServerThread(s)).start(); 22 } 23 } 24 25} 26 27 28package TalkRoom; 29 30import java.io.BufferedReader; 31import java.io.IOException; 32import java.io.InputStreamReader; 33import java.io.PrintStream; 34import java.net.Socket; 35 36public class ServerThread implements Runnable { 37 38 private Socket s; 39 BufferedReader br; 40 41 public ServerThread(Socket s) throws IOException { 42 // TODO Auto-generated constructor stub 43 this.s=s; 44 //初始化该socket对应的输入流 45 br=new BufferedReader(new InputStreamReader(s.getInputStream())); 46 } 47 48 @Override 49 public void run() { 50 // TODO Auto-generated method stub 51 try { 52 String content=null; 53 //采用循环不断从socket中读取客户端发送来的数据 54 while((content=readFromClient())!=null) { 55 //遍历list中的每一个socket 56 //将读到的content像每一个socket发送一次 57 for(Socket s:MyServer.list) { 58 PrintStream ps=new PrintStream(s.getOutputStream()); 59 ps.println(content); 60 } 61 } 62 } catch (IOException e) { 63 // TODO: handle exception 64 e.printStackTrace(); 65 } 66 } 67 68 private String readFromClient() { 69 // TODO Auto-generated method stub 70 try { 71 return br.readLine(); 72 } catch (IOException e) { 73 // TODO: handle exception 74 //捕获到异常说明该socket已关闭,则从list中删除该socket 75 MyServer.list.remove(s); 76 } 77 return null; 78 } 79 80} 81 82 83package TalkRoom; 84 85import java.io.BufferedReader; 86import java.io.IOException; 87import java.io.InputStreamReader; 88import java.io.PrintStream; 89import java.net.Socket; 90import java.net.UnknownHostException; 91 92public class MyClient { 93 94 public static void main(String[] args) throws UnknownHostException, IOException { 95 // TODO Auto-generated method stub 96 Socket s=new Socket("127.0.0.1", 8888); 97 //客户端启动ClientThread线程不断地从server读取数据 98 new Thread(new ClientThread(s)).start(); 99 //获取该socket对应的输出流 100 PrintStream ps=new PrintStream(s.getOutputStream()); 101 String line=null; 102 //不断地读取键盘输入的信息 103 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); 104 while((line=br.readLine())!=null) { 105 //将用户键盘输入的内容不断地输入到socket的输出流中 106 ps.println(line); 107 } 108 } 109 110} 111 112 113package TalkRoom; 114 115import java.io.BufferedReader; 116import java.io.IOException; 117import java.io.InputStreamReader; 118import java.net.Socket; 119 120public class ClientThread implements Runnable { 121 122 private Socket s; 123 BufferedReader br; 124 125 public ClientThread(Socket s) throws IOException { 126 // TODO Auto-generated constructor stub 127 this.s=s; 128 br=new BufferedReader(new InputStreamReader(s.getInputStream())); 129 } 130 131 132 @Override 133 public void run() { 134 // TODO Auto-generated method stub 135 try { 136 String context=null; 137 while((context=br.readLine())!=null) { 138 System.out.println(context); 139 } 140 } catch (IOException e) { 141 // TODO: handle exception 142 e.printStackTrace(); 143 } 144 } 145 146}

初步实现了一个多人聊天室的功能,虽然没有图形界面,但是也能更进一步了解多线程以及Server、Client交互的实现。

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

mysql设置时区

mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0

Java——网络编程(实现基于命令行的多人聊天室) - HelloWorld