Java多线程局域网聊天室 Java多线程局域网聊天室的实现
一只特立独行的猫 人气:0局域网聊天室
在学习了一个学期的java以后,觉得java真是博大精深,彻底放弃了因为c++而轻视java的心态,搞了一个多线程的聊天室,熟悉了一下服务器和客户机的操作。
1.TCP
要实现局域网连接,就必须知道信息传输的原理。
在局域网里面传输的信息都是以包的形式,我使用的TCP包传输数据,TCP包里面封装了IP报文。
下面这句话就是通过一个静态IPV4协议的类得到一个服务器的IP地址。
address = InetAddress.getByName("192.168.43.86");
2.套接字
在TCP中得到了服务器的IP地址,但是光凭IP地址无法对具体应用进行锁定,所以引入了套接字这个概念。端口号用来锁定主机的进程。端口号一般取1024~49151,因为0 ~ 1023是熟知端口号,一般用于一些HTTP等等常用的端口,49152 ~ 65535是临时端口号,也不能随机占用,一般是程序运行过程中的临时分配。
套接字=IP+端口号
这句话就是定义一个端口号9998和IP为192.168.43.86的套接字。
int port = 9998; socket = new Socket(address,port);
3.C/S架构
从Java类的角度看,服务器和客户端通过套接字连接抽象了一个连接。服务器通过建立自己的套接字端口并监听有无客户在此端口连接,实现信息的读取功能。客户机通过服务器约定好的端口号,来对服务器进行传输数据。在服务器开启后,运行客户机,将与服务器进行三次握手建立TCP连接,然后在此连接的基础上,实现客户机与服务器的通信。
4.多线程
由于服务器可能同时服务多个对象,若是采用传统的方法进行服务器连接,则会出现多个客户机等待一个客户机与服务器交互的现象。为了解决这个问题,采用多线程的方法。
用SuperSocket类继承socket类并实现Runnable接口,实现多线程运行。
class SuperSocket extends Socket implements Runnable
SuperSocket socket_1 = new SuperSocket(9999); SuperSocket socket_2 = new SuperSocket(9998); SuperSocket socket_3 = new SuperSocket(9997); Thread s1 = new Thread(socket_1); Thread s2 = new Thread(socket_2); Thread s3 = new Thread(socket_3);
5.服务器
服务器的架构第三部分所示,代码实现如下
package TCP; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class TCPserver2 { public static void main(String[] args) { Scanner scan = new Scanner(System.in); //实例化具有多线程功能的服务器专用socket类 //需要传递端口号作为初始化变量 SuperSocket socket_1 = new SuperSocket(9996); SuperSocket socket_2 = new SuperSocket(9998); SuperSocket socket_3 = new SuperSocket(9997); //建立三个子线程 Thread s1 = new Thread(socket_1); Thread s2 = new Thread(socket_2); Thread s3 = new Thread(socket_3); try { while(true) { //开启线程 s1.start(); s2.start(); s3.start(); if(scan.next()=="123"){ //结束线程 break; } } } finally { try { //关闭套接字 socket_1.close(); socket_2.close(); socket_3.close(); } catch (IOException e) { e.printStackTrace(); } } } } class SuperSocket extends Socket implements Runnable{ InputStream is; byte[] buffer; Socket socket=null; ServerSocket serverSocket=null; public SuperSocket(int port){ try { //初始服务器型套接字 serverSocket = new ServerSocket(port); buffer = new byte[1024]; } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { try { //等待端口连接 socket = serverSocket.accept(); //连接完成后创建输入流 is = socket.getInputStream(); //读取客户端传送信息 int len = is.read(buffer); String str = new String(buffer, 0, len); System.out.println(str); } catch (IOException e) { e.printStackTrace(); } } }
客户端
客户端的架构第三部分所示,代码实现如下
package TCP; import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.Scanner; public class TCPclient { public static void main(String[] args) { InetAddress address=null; Socket socket=null; OutputStream os=null; String message=null; Scanner sca=null; try { //得到本机IP地址 address = InetAddress.getByName("192.168.43.86"); //规定端口号,建立套接字 int port = 9998; socket = new Socket(address,port); //绑定套接字的输出流 os = socket.getOutputStream(); sca = new Scanner(System.in); while(true) { message = sca.next(); //写入输出流,在局域网中传输 os.write(message.getBytes()); } } catch (UnknownHostException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); }finally { try { //关闭端口号,关闭io流 os.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
搞定,虽然特别简陋,但是也能实现局域网类的通信。如果需要复制代码的,记得改一下服务器的IP地址,IP地址可以在cmd下用ipconfig命令查看。打算期末考试完了以后再加上GUI并把这个功能加到具有alpha剪枝算法的AI六子棋对战中去。
加载全部内容