Java Tcp Socket聊天系统模型.docx
《Java Tcp Socket聊天系统模型.docx》由会员分享,可在线阅读,更多相关《Java Tcp Socket聊天系统模型.docx(53页珍藏版)》请在冰豆网上搜索。
JavaTcpSocket聊天系统模型
TcpSocekt通信模型
TcpSocket是面向连接的,所以Server端的accept()方法,一直等着客户端的连接,如果连接成功,则两者进行通信,这种是同步的,因为accept()一直在那儿等着,时刻的等着,实际中的聊天系统是采用异步方式,当有请求的时候就调用accept()方法,没有请求的时候该做什么就做什么去,不需要在那儿等着,不浪费资源,一种异步的方式。
这个例子只是为了学习线程而准备的。
端口有TCP端口和UDP端口两种,端口号都是从0到65535,TCP端口在3层,UDP不是四层就是7层TCP和UDP的协议也不相同,TCP比UDP安全,更多TCP和UDP区别上google,baidu。
服务器端编码
Java代码
1.import java.io.BufferedReader;
2.import java.io.IOException;
3.import java.io.InputStreamReader;
4.import java.io.PrintStream;
5.import .ServerSocket;
6.import .Socket;
7.import java.util.StringTokenizer;
8.import java.util.Vector;
9.
10./**
11. * 服务器端编码
12. * @author 欧阳平 2009-3-17
13. */
14.public class ChatServer {
15. static int port = 5566;//端口号
16. static Vector clients = new Vector(10);//存储连接客户信息
17. static ServerSocket server = null; //建立服务器socket
18. static Socket socket = null; //套接字连接
19. /**
20. * Constructs
21. */
22. public ChatServer() {
23. try {
24. System.out.println("Server start...");
25. server = new ServerSocket(port); //初始化服务器套接字
26. while (true) {
27. socket = server.accept(); //等待连接
28. System.out.println(socket.getInetAddress()+"连接\n");//得到客户机地址
29. Client client = new Client(socket); //实例化一个客户线程(其中线程Client中有Socket,这里的的Socket只是起个过度作用)
30. //
31. clients.add(client);//增加客户线程到向量中
32. client.start();//启动线程
33. notifyChatRoom(); //监视聊天室连接变化
34. }
35. } catch (Exception ex) {
36. ex.printStackTrace();//输出出错信息
37. }
38. }
39.
40. public static void notifyChatRoom() { //监视客户端线程
41. StringBuffer newUser = new StringBuffer("newUser");
42. for (int i = 0; i < clients.size(); i++) {
43. Client c = (Client)clients.elementAt(i);
44. newUser.append(":
"+c.name); //客户端姓名字符串
45. }
46. sendClients(newUser);//发送信息到客户端
47. }
48.
49. public static void sendClients(StringBuffer message) {
50. for (int i= 0 ; i < clients.size(); i++) {
51. Client client = (Client)clients.elementAt(i);//分别得到每个客户端的连接
52. client.send(message);//发送信息
53. }
54. }
55.
56. public void closeAll() { //关闭所有连接
57. while (clients.size() > 0 ) { //遍历整个Vector
58. Client client = (Client) clients.firstElement(); //得到一个客户端
59. try {
60. client.socket.close();
61. } catch(IOException ex) {
62. ex.printStackTrace(); // 输出错误信息
63. }
64. clients.removeElement(client); //移出客户端
65. }
66. }
67.
68. public static void disconnect(Client c) {// 断开客户端
69. try {
70. System.err.println(c.ip+"断开连接\n");
71. } catch (Exception ex) {
72. ex.printStackTrace();
73. }
74. clients.removeElement(c);
75. c.socket = null;
76. }
77.
78.
79. /**
80. * main方法
81. * @param args
82. */
83. public static void main(String[] args) {
84. new ChatServer();
85.
86. }
87. class Client extends Thread {
88. Socket socket;//连接端口
89. String name ;//用户姓名
90. String ip; //客户端ip地址
91. BufferedReader reader;//输入流
92. PrintStream ps;//输出流
93. public Client(Socket s) {
94. socket = s;
95. try {
96. reader = new BufferedReader(new InputStreamReader(s.getInputStream()));//得到输入流
97. ps = new PrintStream(s.getOutputStream());//得到输出流
98. String info = reader.readLine();//读取接收到的信息
99. StringTokenizer stinfo = new StringTokenizer(info,":
"); //分解字符串
100. String head = stinfo.nextToken(); //获取关键字
101. System.out.println(stinfo.toString());
102. System.out.println(head);
103. if (stinfo.hasMoreTokens()){
104. name = stinfo.nextToken() ;//获取用户名
105. }
106. if (stinfo.hasMoreTokens()) {
107. ip = stinfo.nextToken(); //获取IP地址
108. }
109. } catch (IOException ex) {
110. ex.printStackTrace();
111. }
112. System.out.println(name);
113. System.out.println(ip);
114. }
115.
116. public void send (StringBuffer msg) {
117. ps.println(msg); //输出信息
118. ps.flush();
119. }
120. public void run() {
121. while (true) {
122. String line = null;
123. try {
124.
125. line = reader.readLine();
126. System.out.println("line:
"+line);
127.
128. } catch (IOException ex) {
129. ex.printStackTrace(); //输出错误信息
130. ChatServer.disconnect(this);//断开连接
131. ChatServer.notifyChatRoom();//更新信息
132. return ;
133. }
134. if (line == null) { //客户离开
135. ChatServer.disconnect(this);
136. ChatServer.notifyChatRoom();
137. return ;
138. }
139. StringTokenizer st = new StringTokenizer(line,":
");//分解字符串
140. String keyword = st.nextToken();
141. if (keyword.equals("MSG")) { //发送来的聊天信息
142. StringBuffer msg = new StringBuffer("MSG:
");
143. msg.append(name); //在信息上增加用户名
144. msg.append(st.nextToken("\0\n"));
145. ChatServer.sendClients(msg);//发送聊天语句到各个客户端
146. System.out.println(msg);
147. } else if (keyword.equals("quit")) { //退出命令
148. ChatServer.disconnect(this); //断开连接
149. ChatServer.notifyChatRoom(); //刷新信息
150. }
151. }
152. }
153. }
154.
155.}
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintStream;
import.ServerSocket;
import.Socket;
importjava.util.StringTokenizer;
importjava.util.Vector;
/**
*服务器端编码
*@author欧阳平2009-3-17
*/
publicclassChatServer{
staticintport=5566;//端口号
staticVectorclients=newVector(10);//存储连接客户信息
staticServerSocketserver=null;//建立服务器socket
staticSocketsocket=null;//套接字连接
/**
*Constructs
*/
publicChatServer(){
try{
System.out.println("Serverstart...");
server=newServerSocket(port);//初始化服务器套接字
while(true){
socket=server.accept();//等待连接
System.out.println(socket.getInetAddress()+"连接\n");//得到客户机地址
Clientclient=newClient(socket);//实例化一个客户线程(其中线程Client中有Socket,这里的的Socket只是起个过度作用)
//
clients.add(client);//增加客户线程到向量中
client.start();//启动线程
notifyChatRoom();//监视聊天室连接变化
}
}catch(Exceptionex){
ex.printStackTrace();//输出出错信息
}
}
publicstaticvoidnotifyChatRoom(){//监视客户端线程
StringBuffernewUser=newStringBuffer("newUser");
for(inti=0;iClientc=(Client)clients.elementAt(i);
newUser.append(":
"+c.name);//客户端姓名字符串
}
sendClients(newUser);//发送信息到客户端
}
publicstaticvoidsendClients(StringBuffermessage){
for(inti=0;iClientclient=(Client)clients.elementAt(i);//分别得到每个客户端的连接
client.send(message);//发送信息
}
}
publicvoidcloseAll(){//关闭所有连接
while(clients.size()>0){//遍历整个Vector
Clientclient=(Client)clients.firstElement();//得到一个客户端
try{
client.socket.close();
}catch(IOExceptionex){
ex.printStackTrace();//输出错误信息
}
clients.removeElement(client);//移出客户端
}
}
publicstaticvoiddisconnect(Clientc){//断开客户端
try{
System.err.println(c.ip+"断开连接\n");
}catch(Exceptionex){
ex.printStackTrace();
}
clients.removeElement(c);
c.socket=null;
}
/**
*main方法
*@paramargs
*/
publicstaticvoidmain(String[]args){
newChatServer();
}
classClientextendsThread{
Socketsocket;//连接端口
Stringname;//用户姓名
Stringip;//客户端ip地址
BufferedReaderreader;//输入流
PrintStreamps;//输出流
publicClient(Sockets){
socket=s;
try{
reader=newBufferedReader(newInputStreamReader(s.getInputStream()));//得到输入流
ps=newPrintStream(s.getOutputStream());//得到输出流
Stringinfo=reader.readLine();//读取接收到的信息
StringTokenizerstinfo=newStringTokenizer(info,":
");//分解字符串
Stringhead=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(IOExceptionex){
ex.printStackTrace();
}
System.out.println(name);
System.out.println(ip);
}
publicvoidsend(StringBuffermsg){
ps.println(msg);//输出信息
ps.flush();
}
pub