package T22;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
/*
* 使用TCP/IP协议实现C/S架构的网络通讯程序
*
* 1.服务器端:ServerSocket
* 2.客户端:Socket
*
* 端口:port
* 端口的范围从1~65535,1000一下的端口给系统使用,应用开发一般使用1000以上的端口
*
TCP:可靠,传输大小无限制,但是需要时间来建立连接,差错控制开发大;主要用于文本、程序等可靠性高的数据传输。
UDP:不可靠,传输大小限制在64K以下,不需要建立连接,差错控制开销小;主要用于类似图像、声音、网络游戏、
视频会议等等对可靠性要求没有那么高的业务进行传输。
Datagram(数据报):是分组交换的一种形式,就是把所传递的数据分段打成“包”,再传送出去。
与传统的“连接型”分组交换不同,它属于“无连接型”,是把打包成的每个“包”(分组)都作为一个“独立的报文”传送出去,
*所以叫做“数据报”。在开始通信之前不需要先连接好一条线路,各个数据报不一定都通过同一条路径传输。
* */
public class TcpServer2 {
//定义Hashtable保存多个客户信息
Hashtable<Integer,Socket> ht_user = new Hashtable<Integer, Socket>();
public TcpServer2(){
System.out.println("启动服务器。。。。。。");
try {
//1.创建ServerSocket
ServerSocket serverSocket = new ServerSocket(8888);
//2.监听,等待客户端连接(如果没有客户端连接进来,程序停留在该行语句,不会再往下执行)
while(true) {
Socket client = serverSocket.accept(); //一个socket对象代表一个客户端
System.out.println("创建服务器成功,等待客户端连接。。。。。。");
//启动线程
new ReceiveThread(client).start();
}
}catch (Exception e){
e.printStackTrace();
}
}
//服务器端程序,一定要先启动,客户端才能连接
public static void main(String[] args) {
new TcpServer2();
}
//内部类,接收线程
class ReceiveThread extends Thread{
Socket socket;
public ReceiveThread(Socket socket){
this.socket = socket;
//保存到集合
ht_user.put(socket.hashCode(),socket);
System.out.println("hashcode=" + socket.hashCode());
}
@Override
public void run() {
try {
//3.获取输入流(接收数据)
InputStream is = socket.getInputStream();
//输入流转换为字符流
BufferedReader br = new BufferedReader(new InputStreamReader(is));
while (true) {
//获取输入内容
String str = br.readLine();
if(str==null){
continue;
}
System.out.println(str);
str = "【"+socket.hashCode()+"】说:" + str;
//群发
Set<Integer> set = ht_user.keySet();
Iterator<Integer> it = set.iterator();
while(it.hasNext()) {
//调用send方法发送
send(ht_user.get(it.next()),str);
}
}
}catch (Exception e) {
e.printStackTrace();
}
}
public void send(Socket socket,String str) {
try {
//获取输出流
OutputStream os = socket.getOutputStream();
PrintStream ps = new PrintStream(os);
ps.println(str);
}catch (Exception e){
e.printStackTrace();
}
}
}
}