用tcp的socket通信方法写的多人聊天总结

用tcp的socket通信方法写的多人聊天总结

  • 实现效果,一个客户端发送,所有客户端都可以接受到
简单介绍一下Socket原理
  • 它提供一个服务器,响应客户端的连接请求,响应成功后就会为客户端创建一个服务器端的socket来与客户端进行通信,并为他来分配一个未使用的端口
  • 服务器和客户端创建之初需要自行指定一个未使用的端口号,他的作用是当客户端需要请求连接时,就会拿着实现指定的端口去寻找具有该端口号的服务器去请求连接,不然不事先指定的话客户端怎么知道服务器在哪里呢?
  • 当服务器响应请求成功之后此时客户端就会有一个服务器端的socket与它遥遥相对,而这两者间存在着输入输出流管道,于是可以进行数据的通信

  • 当建立多个客户端时的原理是一样的
接下来上代码看一下

先是服务器端

  • 服务器做的工作是将所有连接过的服务器端的socket放在一个集合中
  • 然后对每一个服务器端的socket开一个监听线程,如果这个服务器端的socket的输入流有数据发送来,就会读取数据并把所有数据放松给集合中所有服务器端的socket的输出流
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class Receive {

private static List<Socket> serverlist = new ArrayList<>();
private static ServerSocket serverSocket = null;
public static void main(String[] args){
try{
serverSocket = new ServerSocket(30000);
System.out.println("等待客户端连接...");
} catch(IOException e) {
e.printStackTrace();
}
while (!serverSocket.isClosed()){
Socket socket = null;
try{
while(!serverSocket.isClosed()){
socket = serverSocket.accept();
System.out.println("连接成功");
serverlist.add(socket);
new receiveCilent(socket).start();
}
}catch (IOException e){
e.printStackTrace();
}finally{
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 得到该客户端的输出流数据,输出至集合中各个客户端的输入流
*
*/

static class receiveCilent extends Thread {
private Socket s;
private InputStream os;
public receiveCilent(Socket s) {
this.s = s;
try{
os = s.getInputStream();
}catch(IOException e){
e.printStackTrace();
}
}
public void run() {
byte[] bt = new byte[1024*1024];
try {
int l = 0;
while(true){
if( !s.isClosed() && (l = os.read(bt)) != -1){
String str = new String(bt, 0,l);
System.out.println(str);
for(Socket socket:serverlist){
OutputStream os = socket.getOutputStream();
os.write(str.getBytes());
os.flush();
//把数据写入到每个客户端的输入流
}
}

}

} catch (IOException e) {
e.printStackTrace();
}finally{
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

客户端

  • 客户端做的是连接成功后开两个线程,一个监听键盘输入数据,并及时将数据发送到服务器端对应的socket 
    一个线程负责接收服务器端socket发来的数据并显示
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class Send {
public static void main(String[] args) throws IOException, IOException {
Socket s = new Socket("yanghao", 30000);
Scanner in = new Scanner(System.in);
new sendThread(s).start();
new receivedata(s).start();
while(!s.isClosed()){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
in.close();
}
}
/**
* 从客户端的输入流读取数据显示在控制台
* @author yanghao
*
*/

class receivedata extends Thread{
private Socket s = null;
private InputStream is = null;

public receivedata(Socket s2) {
this.s = s2;
try {
is = s.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run(){
byte[] bt = new byte[1024*1024];
int l;
try {
while( !s.isClosed() && is != null){
l = is.read(bt);
System.out.println(new String(bt,0,l));
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try{
is.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
/**
* 从键盘读入数据,写入客户端的输出流
* @author yanghao
*
*/

class sendThread extends Thread{
private Socket s = null;
private Scanner in = new Scanner(System.in);
private OutputStream os = null;
public sendThread(Socket s) {
this.s = s;
try {
os = s.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
String str = new String();
while(!s.isClosed()){
str = in.nextLine();
os.write(str.getBytes());
os.flush();
}
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这个时候就实现了一个客户端发送数据其他所有客户端都可以接收到数据的操作

总结

  • 在Java的控制台这样搞明显是特别麻烦,所以感兴趣的小伙伴可以给它加一个GUI界面
  • 为了数据传输的方便,在获取到字节输入输出流是可以将其包装一下,对象流,带缓冲区的字符流等,
  • 还可以设置客户端关闭之后自动的关闭服务器端的socket,这个我个人的思路是在finally语句中发送一个大家公认的信息,当客户端非异常情况下关闭时,服务器端的socket就会接收到客户端关闭的信息,以便及时关闭服务器端的socket,节省资源
各位小伙伴可以尽情提建议,纯新手程序,不喜勿喷
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值