`

Java Tcp Socket聊天系统模型(主要为了学习线程)

阅读更多
TcpSocekt通信模型




Tcp Socket是面向连接的,所以Server端的accept()方法,一直等着客户端的连接,如果连接成功,则两者进行通信,这种是同步的,因为accept()一直在那儿等着,时刻的等着,实际中的聊天系统是采用异步方式,当有请求的时候就调用accept()方法,没有请求的时候该做什么就做什么去,不需要在那儿等着,不浪费资源,一种异步的方式。这个例子只是为了学习线程而准备的。
端口有TCP端口和UDP端口两种,端口号都是从0到65535,TCP端口在3层,UDP不是四层就是7层 TCP和UDP的协议也不相同,TCP比UDP安全,更多TCP和UDP区别上google,baidu。

服务器端编码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;
import java.util.Vector;

/**
 * 服务器端编码
 * @author 欧阳平 2009-3-17 
 */
public class ChatServer {
	static int port = 5566;//端口号
	static Vector<Client> clients = new Vector<Client>(10);//存储连接客户信息
	static ServerSocket server = null; //建立服务器socket
	static Socket socket = null; //套接字连接
	/**
	 * Constructs
	 */
	public ChatServer() {
		try {
			System.out.println("Server start...");
			server  = new ServerSocket(port); //初始化服务器套接字
			while (true) {
				socket = server.accept(); //等待连接
				System.out.println(socket.getInetAddress()+"连接\n");//得到客户机地址
				Client client = new Client(socket); //实例化一个客户线程(其中线程Client中有Socket,这里的的Socket只是起个过度作用)
				//
				clients.add(client);//增加客户线程到向量中
				client.start();//启动线程
				notifyChatRoom(); //监视聊天室连接变化
			}
		} catch (Exception ex) {
			ex.printStackTrace();//输出出错信息
		}
	}
	
	public static void notifyChatRoom() { //监视客户端线程
		StringBuffer newUser = new StringBuffer("newUser");
		for (int i = 0; i < clients.size(); i++) {
			Client c = (Client)clients.elementAt(i);
			newUser.append(":"+c.name); //客户端姓名字符串
		}
		sendClients(newUser);//发送信息到客户端
	}
	
	public static void sendClients(StringBuffer message) {
		for (int i= 0 ; i < clients.size(); i++) {
			Client client = (Client)clients.elementAt(i);//分别得到每个客户端的连接
			client.send(message);//发送信息
		}
	}
	
	public void closeAll() { //关闭所有连接
		while (clients.size() > 0 ) { //遍历整个Vector
			Client client = (Client) clients.firstElement(); //得到一个客户端
			try {
				client.socket.close();
			} catch(IOException ex) {
				ex.printStackTrace(); // 输出错误信息
			}
			clients.removeElement(client); //移出客户端
		}
	}
	
	public static void disconnect(Client c) {// 断开客户端
		try {
			System.err.println(c.ip+"断开连接\n");
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		clients.removeElement(c);
		c.socket = null;
	}
	
	
	/**
	 * main方法
	 * @param args
	 */
	public static void main(String[] args) {
		new ChatServer();

	}
	class Client extends Thread {
		Socket socket;//连接端口
		String name ;//用户姓名
		String ip; //客户端ip地址
		BufferedReader reader;//输入流
		PrintStream ps;//输出流
		public Client(Socket s) {
			socket = s;
			try {
				reader = new BufferedReader(new InputStreamReader(s.getInputStream()));//得到输入流
				ps = new PrintStream(s.getOutputStream());//得到输出流
				String info = reader.readLine();//读取接收到的信息
				StringTokenizer stinfo = new StringTokenizer(info,":"); //分解字符串
				String head = stinfo.nextToken(); //获取关键字
				System.out.println(stinfo.toString());
				System.out.println(head);
				if (stinfo.hasMoreTokens()){
					name = stinfo.nextToken() ;//获取用户名
				}
				if (stinfo.hasMoreTokens()) {
					ip = stinfo.nextToken(); //获取IP地址
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
			System.out.println(name);
			System.out.println(ip);
		}
		
		public void send (StringBuffer msg) {
			ps.println(msg); //输出信息
			ps.flush();
		}
		public void run() {
			while (true) {
				String line = null;
				try {
					
					line = reader.readLine();
					System.out.println("line:"+line);
					
				} catch (IOException ex) {
					ex.printStackTrace(); //输出错误信息
					ChatServer.disconnect(this);//断开连接
					ChatServer.notifyChatRoom();//更新信息
					return ;
				}
				if (line == null) { //客户离开
					ChatServer.disconnect(this);
					ChatServer.notifyChatRoom();
					return ;
				}
				StringTokenizer st = new StringTokenizer(line,":");//分解字符串
				String keyword = st.nextToken();
				if (keyword.equals("MSG")) { //发送来的聊天信息
					StringBuffer msg = new StringBuffer("MSG:");
					msg.append(name); //在信息上增加用户名
					msg.append(st.nextToken("\0\n"));
					ChatServer.sendClients(msg);//发送聊天语句到各个客户端
					System.out.println(msg);
				} else if (keyword.equals("quit")) { //退出命令
					ChatServer.disconnect(this); //断开连接
					ChatServer.notifyChatRoom(); //刷新信息
				}
			}
		}
	}
	
}




//客户端编码
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Label;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.StringTokenizer;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * 基于Socket网络聊天程序 客户端编码
 * @author 欧阳平 2009-3-17 
 */
public class ChatClient extends JFrame  implements ActionListener,Runnable{
	
	TextField tfName = new TextField(15);//姓名输入文本域
	Button btConnect = new Button("连接");//连接按钮
	Button btDisconnect = new Button("断开连接");//断开连接按钮
	TextArea tfChat = new TextArea(8,27);//显示聊天信息文本域
	Button btSend = new Button("发送");
	TextField tfMessage = new TextField(30);//聊天输入
	java.awt.List list1  = new java.awt.List(9);//显示在线用户信息 
	Socket socket = null;//连接端口
	PrintStream ps = null;//输出流
	Listen listen = null;
	//监听线程类
	class Listen extends Thread {
		BufferedReader reader;
		PrintStream ps;
		String cname;
		Socket socket;
		ChatClient chatClient;
		public Listen(ChatClient client,String name,Socket socket) {
			try {
				this.chatClient = client;
				 this.socket = socket;
				 this.cname = name;
				 reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				 ps = new PrintStream(socket.getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		public void run() {
			while (true) {
				String line=null ;
				try {
				line = reader.readLine(); //读取数据流
				System.out.println("客户端:"+line);
				
			}catch (IOException ex) {
				ex.printStackTrace();
				ps.println("quit");; //断开连接
				return;
			}
			StringTokenizer stinfo = new StringTokenizer(line,":"); //分解字符串
			String keyword = stinfo.nextToken();
			if (keyword.equals("MSG")) {
				chatClient.tfChat.append(line+"\n");
			}
			else if (keyword.equals("newUser")){
				chatClient.list1.clear();
				chatClient.list1.add("users", 0);
				int i = 1;
				while (stinfo.hasMoreTokens()) {
					chatClient.list1.add(stinfo.nextToken(), i++);
				}
			}
	   	}
		
	  }
	}
	public void actionPerformed(ActionEvent e) {
		try{
			if(e.getSource()==btConnect) { //点击连接按钮
				if (socket == null) {
					socket = new Socket(InetAddress.getLocalHost(),5566);//实例化一个套接字
					ps = new PrintStream(socket.getOutputStream());//获取输出流,写入信息
					StringBuffer info = new StringBuffer("info:");
					String userinfo = tfName.getText()+":"+InetAddress.getLocalHost().toString();
					ps.println(info.append(userinfo));//输出信息
					ps.flush();
					listen = new Listen(this,tfName.getText(),socket);
					listen.start();
				}
			} else if (e.getSource() == btDisconnect) { //点击断开连接按钮
				disconnect();
			} else if (e.getSource() == btSend) { //点击发送按钮
				if (socket != null) {
					StringBuffer msg = new StringBuffer("MSG:");
					String msgtxt = new String(tfMessage.getText());
					ps.println(msg.append(msgtxt));//发送信息
					ps.flush();
				} else {
					JOptionPane.showMessageDialog(this, "请先连接!", "提示", 1);
				}
			}
			
		} catch (Exception ex) {
			ex.printStackTrace();//输出错误信息
		}
	}
	public void disconnect() { //断开连接方法
		if (socket != null) {
			ps.println("quit");//发送信息
			ps.flush();
			
			socket = null;
			tfName.setText("");
		}
	}
	
	
	
	
	
	

	
	public ChatClient(Socket socket) {
		
		
		this.setLayout(new BorderLayout());
		
		JPanel panel1 = new JPanel();
		Label label = new Label("姓名");
		panel1.setBackground(Color.orange);
		panel1.add(label);
		panel1.add(tfName);
		panel1.add(btConnect);
		panel1.add(btDisconnect);
		this.add(panel1,BorderLayout.NORTH);
		
		JPanel panel2 = new JPanel();
		panel2.add(tfChat);
		panel2.add(list1);
		this.add(panel2,BorderLayout.CENTER);
		
		JPanel panel3 = new JPanel();
		Label label2 = new Label("聊天信息");
		panel3.add(label2);
		panel3.add(tfMessage);
		panel3.add(btSend);
		this.add(panel3,BorderLayout.SOUTH);
		
		this.setBounds(50,50,400,350);
		this.setVisible(true);
		
		btConnect.addActionListener(this);
		btDisconnect.addActionListener(this);
		btSend.addActionListener(this);
		
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ChatClient client = new ChatClient(new Socket());
		System.out.println(client.socket);
	}


在想做东西的时候,不能只拿着代码就想编程,先搞清楚原理规则,然后动手实践,否则事倍功半!了解规则,熟悉规则。
分享到:
评论
1 楼 salever 2011-09-15  
不错,貌似少一点超时设置

相关推荐

    Java_Tcp_Socket聊天系统模型

    Java TCP Socket聊天系统模型是一种基于Java编程语言实现的网络通信模型,主要用于构建在线聊天系统。TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输层协议,确保数据在发送方和接收方之间完整...

    java socket 聊天系统

    Java Socket聊天系统是一种基于TCP/IP协议的网络通信应用,它允许两台计算机通过互联网进行双向通信。在这个系统中,Socket充当了通信的桥梁,为应用程序提供了低级别的、面向连接的网络服务。Java的Socket类和...

    Java TCP IP Socket编程(原书第2版)

    《Java TCP/IP Socket编程》(原书第2版)是一本深入探讨Java中Socket编程的专著,旨在帮助读者理解并掌握如何在Java环境中利用TCP/IP协议进行网络通信。本书不仅详细介绍了Socket的工作原理,还提供了丰富的示例...

    java写的一个简单基于tcp协议的多用户聊天系统

    在本项目中,我们探讨的是一个使用Java(J2SE)编写的简单多用户聊天系统,该系统基于TCP协议。TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,它确保了数据的正确顺序传输和无丢失,...

    socket TCP网络聊天室编程

    本项目名为"socket TCP网络聊天室编程",其主要目标是创建一个支持多人聊天、离线消息存储以及文件传输功能的聊天平台。下面将详细阐述相关知识点。 首先,TCP(Transmission Control Protocol)是一种面向连接的、...

    Java Socket 聊天通信演示代码

    Java Socket 是一种网络通信协议,它是Java编程语言中实现客户端-服务器模型的基础。Socket 提供了低级别的、面向连接的、双向通信的网络接口,允许应用程序通过网络进行数据传输。在本示例中,我们将深入探讨Java ...

    Java TCP IP Socket编程 包含源码

    Java TCP/IP Socket编程是网络通信领域中的核心技术,广泛应用于服务器端和客户端之间的数据...通过学习和实践这些知识点,开发者能够熟练掌握Java环境下的TCP/IP Socket编程,从而构建出高效、稳定的网络应用程序。

    精选_基于JAVA和TCP SOCKET实现的P2P的局域网即时通信系统_源码打包

    标题中的“精选_基于JAVA和TCP SOCKET实现的P2P的局域网即时通信系统_源码打包”表明这是一个使用Java编程语言,并依赖TCP套接字(Socket)技术开发的P2P(对等网络)局域网即时通信系统。这个系统允许在局域网内的...

    Java_TCP_IP_Socket编程(原书第2版)

    Java TCP/IP Socket编程是网络通信领域中的核心技术,尤其在Java平台中,Socket是实现客户端与服务器之间通信的基础。原书第二版深入浅出地讲解了Java Socket编程的各个方面,为开发者提供了全面的学习资源。以下是...

    基于Socket网络聊天系统的设计与实现

    基于Socket网络聊天系统的设计与实现是指使用Java应用程序设计,基于Client/Server模型,使用Eclipse作为开发环境,MySQL作为后台数据库,利用JDBC连接数据库的网络聊天系统。该系统主要包括服务器模块和客户端模块...

    tcp.rar_java socket 服务端_java tcp socket_服务端 客户端

    Java的Socket类提供了对TCP协议的支持,使得开发者能够构建服务器端(Server)和客户端(Client)的应用程序。本示例中的"tcp.rar"压缩包包含了实现TCP通信的Java代码,包括"TCPClient.java"和"TCPServer.java"两个...

    java tcp 基于socket的聊天室系统

    Java TCP基于Socket的聊天室系统是一种使用网络编程基础——Socket接口来实现实时通信的应用。在Java中,Socket是提供客户端-服务器模型通信的核心组件,它允许两台计算机通过网络交换数据。在这个系统中,一台...

    Java Socket-03 Java TCP Socket

    这两个示例文件是典型的TCP客户端-服务器交互模型,它们演示了如何使用Java Socket API创建简单的通信程序。在实际应用中,可能需要考虑错误处理、多线程(处理多个客户端连接)以及更复杂的数据格式化和解析等高级...

    java TCP/IP socket 编程(原书第2版)pdf+源码

    在Java中,TCP/IP Socket编程主要涉及应用层和传输层,特别是TCP协议,它提供了一种面向连接、可靠的数据传输服务。 在Java中,Socket类和ServerSocket类是TCP/IP通信的主要接口。ServerSocket用于创建服务器端的...

    Java+TCP/IP+Socket编程++原书第2版.pdf

    在Java中,我们主要关注应用层的Socket接口和传输层的TCP协议。TCP是一种面向连接的、可靠的传输协议,它确保了数据的有序、无损传输。而Socket则可以看作是两台计算机之间的通信端点,允许它们通过TCP/IP交换数据。...

    java基于TCP/IP的聊天室

    为了实现这一点,服务器需要维护一个客户端连接列表,并用多线程或者异步IO模型来处理并发连接。 **客户端**则是用户与聊天室交互的界面。它首先需要连接到服务器,通过输入用户名和选择服务器端的IP地址和端口号...

    java tcp聊天系统

    总的来说,这个Java TCP聊天系统项目涵盖了网络编程、GUI设计和多线程等核心Java技术,对于学习和理解Java的实用性和灵活性具有很好的实践价值。通过深入研究这个项目,开发者不仅可以提升Java编程能力,还能掌握TCP...

    基于TCP/IP协议下的聊天系统

    【基于TCP/IP协议下的聊天系统】是一个典型的网络通信应用,主要利用了计算机网络中的Socket编程技术。TCP/IP协议是互联网上最广泛使用的通信协议栈,它由多个层次组成,包括应用层、传输层、网络层和数据链路层。在...

    Java TCP-IP Socket编程-卡尔弗特.pdf

    Java TCP/IP Socket编程是网络通信领域中的核心技术,尤其在Java编程中,Socket是实现客户端与服务器之间通信的基础。本资料“Java TCP-IP Socket编程-卡尔弗特.pdf”旨在深入探讨如何利用Java语言进行TCP/IP套接字...

    Java TCP IP Socket编程(中文版).pdf

    在计算机网络领域,TCP/IP是一组用于互联网数据传输的协议,而Socket编程则是实现这些协议功能...通过上述知识点的介绍,可以了解Java TCP/IP Socket编程的基础和进阶内容,以及如何利用Java语言开发高性能的网络应用。

Global site tag (gtag.js) - Google Analytics