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