第
步 充分理解Socket
1.什么是
所谓
通常也称作"套接字"
用于描述IP地址和端口
是
个通信链
句柄
应用
通常通过"套接字"向网络发出请求或者应答网络请求
以J2SDK-1.3为例
Socket和ServerSocket类库位于java.net包中
ServerSocket用于服务器端
Socket是建立网络连接时使用
在连接成功时
应用
两端都会产生
个Socket例子
操作这个例子
完成所需
会话
对于
个网络连接来说
套接字是平等
并没有差别
不
在服务器端或在客户端而产生区别级别
不管是Socket还是ServerSocket它们
工作都是通过SocketImpl类及其子类完成
重要
Socket API:
java.net.Socket继承于java.lang.Object
有 8个构造器
其思路方法并不多
下面介绍使用最频繁
3个思路方法
其它思路方法大家可以见JDK-1.3文档
. Accept思路方法用于产生"阻塞"
直到接受到
个连接
并且返回
个客户端
Socket对象例子
"阻塞"是
个术语
它使
运行暂时"停留"在这个地方
直到
个会话产生
然后
继续;通常"阻塞"是由循环产生
. getInputStream思路方法获得网络连接输入
同时返回
个IutputStream对象例子
. getOutputStream思路方法连接
另
端将得到输入
同时返回
个OutputStream对象例子
注意:其中getInputStream和getOutputStream思路方法均会产生
个IOException
它必须被捕获
它们返回
流对象
通常都会被另
个流对象使用
2.如何开发
个Server-Client模型
开发原理:
服务器
使用ServerSocket监听指定
端口
端口可以随意指定(由于1024以下
端口通常属于保留端口
在
些操作系统中不可以随意使用
所以建议使用大于1024
端口)
等待客户连接请求
客户连接后
会话产生;在完成会话后
关闭连接
客户端
使用Socket对网络上某
个服务器
某
个端口发出连接请求
旦连接成功
打开会话;会话完成后
关闭Socket
客户端不需要指定打开
端口
通常临时
、动态
分配
个1024以上
端口
{建立服务器}
import java.net.*;
import java.io.*;
public
Server
{
private ServerSocket ss;
private Socket
;
private BufferedReader in;
private Pr
Writer out;
public Server
{
try
{
ss =
ServerSocket(10000);
while (true)
{
= ss.accept
;
in =
BufferedReader(
InputStreamReader(
.getInputStream
));
out =
Pr
Writer(
.getOutputStream
,true);
String line = in.readLine
;
out.pr
ln("you input is :" + line);
out.close
;
in.close
;
.close
;
}
ss.close
;
}
catch (IOException e)
{}
}
public
void
(String
args)
{
Server
;
}
}
这个
建立了
个服务器
它
直监听10000端口
等待用户连接
在建立连接后给客户端返回
段信息
然后结束会话
这个
次只能接受
个客户连接
{建立客户端}
import java.io.*;
import java.net.*;
public
Client
{
Socket
;
BufferedReader in;
Pr
Writer out;
public Client
{
try
{
=
Socket("xxx.xxx.xxx.xxx", 10000);
in =
BufferedReader(
InputStreamReader(
.getInputStream
));
out =
Pr
Writer(
.getOutputStream
,true);
BufferedReader line =
BufferedReader(
InputStreamReader(
.in));
out.pr
ln(line.readLine
);
line.close
;
out.close
;
in.close
;
.close
;
}
catch (IOException e)
{}
}
public
void
(String
args)
{
Client
;
}
}
这个客户端连接到地址为xxx.xxx.xxx.xxx
服务器
端口为10000
并从键盘输入
行信息
发送到服务器
然后接受服务器
返回信息
最后结束会话
第 2步 多个客户同时连接
在实际
网络环境里
同
时间只对
个用户服务是不可行
个优秀
网络服务
除了能处理用户
输入信息
还必须能够同时响应多个客户端
连接请求
在java中
实现以上功能特点是非常容易
设计原理:
主
监听
端口
等待客户接入;同时构造
个线程类
准备接管会话
当
个Socket会话产生后
将这个会话交给线程处理
然后主
继续监听
运用Thread类或Runnable接口来实现是不错
办法
{实现消息共享}
import java.io.*;
import java.net.*;
public
Server extends ServerSocket
{
private
final
SERVER_PORT = 10000;
public Server
throws IOException
{
super(SERVER_PORT);
try
{
while (true)
{
Socket
= accept
;
CreateServerThread(
);
}
}
catch (IOException e)
{}
finally
{
close
;
}
}
//--- CreateServerThread
CreateServerThread extends Thread
{
private Socket client;
private BufferedReader in;
private Pr
Writer out;
public CreateServerThread(Socket s) throws IOException
{
client = s;
in =
BufferedReader(
InputStreamReader(client.getInputStream
, "GB2312"));
out =
Pr
Writer(client.getOutputStream
, true);
out.pr
ln("--- Welcome ---");
start
;
}
public void run
{
try
{
String line = in.readLine
;
while (!line.equals("bye"))
{
String msg = createMessage(line);
out.pr
ln(msg);
line = in.readLine
;
}
out.pr
ln("--- See you, bye! ---");
client.close
;
}
catch (IOException e)
{}
}
private String createMessage(String line)
{
xxxxxxxxx;
}
}
public
void
(String
args) throws IOException
{
Server
;
}
}
这个
监听10000端口
并将接入交给CreateServerThread线程运行
CreateServerThread线程接受输入
并将输入回应客户
直到客户输入"bye"
线程结束
我们可以在createMessage思路方法中
对输入进行处理
并产生结果
然后把结果返回给客户
第 3步 实现信息共享:在Socket上
实时交流
网络
伟大的
也是信息共享
Server可以主动向所有Client广播消息
同时Client也可以向其它Client发布消息
下面看看如何开发
个可以实时传递消息
设计原理:
服务器端接受客户端
连接请求
同时启动
个线程处理这个连接
线程不停
读取客户端输入
然后把输入加入队列中
等候处理
在线程启动
同时将线程加入队列中
以便在需要
时候定位和取出
{源码}
import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.*;
public
Server extends ServerSocket
{
private
ArrayList User_List =
ArrayList
;
private
ArrayList Threader =
ArrayList
;
private
LinkedList Message_Array =
LinkedList
;
private
Thread_Counter = 0;
private
boolean isClear = true;
protected
final
SERVER_PORT = 10000;
protected FileOutputStream LOG_FILE =
FileOutputStream("d:/connect.log", true);
public Server
throws FileNotFoundException, IOException
{
super(SERVER_PORT);
Broadcast
;
//append connection log
Calendar now = Calendar.getInstance
;
String str = "[" + now.getTime
.toString
+ "] Accepted a connection\015\012";
tmp = str.getBytes
;
LOG_FILE.write(tmp);
try
{
while (true)
{
Socket
= accept
;
CreateServerThread(
);
}
}
finally
{
close
;
}
}
public
void
(String
args) throws IOException
{
Server
;
}
//--- Broadcast
Broadcast extends Thread
{
public Broadcast
{
start
;
}
public void run
{
while (true)
{
(!isClear)
{
String tmp = (String)Message_Array.getFirst
;
for (
i = 0; i < Threader.size
; i
)
{
CreateServerThread client = (CreateServerThread)Threader.get(i);
client.sendMessage(tmp);
}
Message_Array.removeFirst
;
isClear = Message_Array.size
> 0 ? false : true;
}
}
}
}
//--- CreateServerThread
CreateServerThread extends Thread
{
private Socket client;
private BufferedReader in;
private Pr
Writer out;
private String Username;
public CreateServerThread(Socket s) throws IOException
{
client = s;
in =
BufferedReader(
InputStreamReader(client.getInputStream
));
out =
Pr
Writer(client.getOutputStream
, true);
out.pr
ln("--- Welcome to this chatroom ---");
out.pr
ln("Input your nickname:");
start
;
}
public void sendMessage(String msg)
{
out.pr
ln(msg);
}
public void run
{
try
{
flag = 0;
Thread_Counter
;
String line = in.readLine
;
while (!line.equals("bye"))
{
(line.equals("l"))
{
out.pr
ln(listOnlineUsers
);
line = in.readLine
;
continue;
}
(flag
0)
{
Username = line;
User_List.add(Username);
out.pr
ln(listOnlineUsers
);
Threader.add(this);
pushMessage("[< " + Username + " come _disibledevent= false;
}
}
}
延伸阅读
最新评论