第一步充分理解Socket
什么是socket
所谓socket通常也称作套接字用于描述IP地址和端口是一个通信链的句柄应用程序通常通过套接字向网络发出请求或者应答网络请求
以JSDK为例Socket和ServerSocket类库位于包中ServerSocket用于服务器端Socket是建立网络连接时使用的在连接成功时应用程序两端都会产生一个Socket实例操作这个实例完成所需的会话对于一个网络连接来说套接字是平等的并没有差别不因为在服务器端或在客户端而产生不同级别不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的
重要的Socket API
Socket继承于javalangObject有八个构造器其方法并不多下面介绍使用最频繁的三个方法其它方法大家可以见JDK文档
Accept方法用于产生阻塞直到接受到一个连接并且返回一个客户端的Socket对象实例阻塞是一个术语它使程序运行暂时停留在这个地方直到一个会话产生然后程序继续通常阻塞是由循环产生的
getInputStream方法获得网络连接输入同时返回一个IutputStream对象实例
getOutputStream方法连接的另一端将得到输入同时返回一个OutputStream对象实例
注意其中getInputStream和getOutputStream方法均会产生一个IOException它必须被捕获因为它们返回的流对象通常都会被另一个流对象使用
如何开发一个ServerClient模型的程序
开发原理
服务器使用ServerSocket监听指定的端口端口可以随意指定(由于以下的端口通常属于保留端口在一些操作系统中不可以随意使用所以建议使用大于的端口)等待客户连接请求客户连接后会话产生在完成会话后关闭连接
客户端使用Socket对网络上某一个服务器的某一个端口发出连接请求一旦连接成功打开会话会话完成后关闭Socket客户端不需要指定打开的端口通常临时的动态的分配一个以上的端口{建立服务器}
import *;
import javaio*;
public class Server
{
private ServerSocket ss;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public Server()
{
try
{
ss = new ServerSocket();
while (true)
{
socket = ssaccept();
in = new BufferedReader(new InputStreamReader(socketgetInputStream()));
out = new PrintWriter(socketgetOutputStream()true);
String line = inreadLine();
outprintln(you input is : + line);
outclose();
inclose();
socketclose();
}
ssclose();
}
catch (IOException e)
{}
}
public static void main(String[] args)
{
new Server();
}
}
这个程序建立了一个服务器它一直监听端口等待用户连接在建立连接后给客户端返回一段信息然后结束会话这个程序一次只能接受一个客户连接
{建立客户端}
import javaio*;
import *;
public class Client
{
Socket socket;
BufferedReader in;
PrintWriter out;
public Client()
{
try
{
socket = new Socket(xxxxxxxxxxxx );
in = new BufferedReader(new InputStreamReader(socketgetInputStream()));
out = new PrintWriter(socketgetOutputStream()true);
BufferedReader line = new BufferedReader(new InputStreamReader(Systemin));
outprintln(linereadLine());
lineclose();
outclose();
inclose();
socketclose();
}
catch (IOException e)
{}
}
public static void main(String[] args)
{
new Client();
}
}
这个客户端连接到地址为xxxxxxxxxxxx的服务器端口为并从键盘输入一行信息发送到服务器然后接受服务器的返回信息最后结束会话
第二步多个客户同时连接
在实际的网络环境里同一时间只对一个用户服务是不可行的一个优秀的网络服务程序除了能处理用户的输入信息还必须能够同时响应多个客户端的连接请求在java中实现以上功能特点是非常容易的
设计原理
主程序监听一端口等待客户接入同时构造一个线程类准备接管会话当一个Socket会话产生后将这个会话交给线程处理然后主程序继续监听运用Thread类或Runnable接口来实现是不错的办法
{实现消息共享}
import javaio*;
import *;
public class Server extends ServerSocket
{
private static final int SERVER_PORT = ;
public Server() throws IOException
{
super(SERVER_PORT);
try
{
while (true)
{
Socket socket = accept();
new CreateServerThread(socket);
}
}
catch (IOException e)
{}
finally
{
close();
}
}
// CreateServerThread
class CreateServerThread extends Thread
{
private Socket client;
private BufferedReader in;
private PrintWriter out;
public CreateServerThread(Socket s) throws IOException
{
client = s;
in = new BufferedReader(new InputStreamReader(clientgetInputStream() GB));
out = new PrintWriter(clientgetOutputStream() true);
outprintln( Welcome );
start();
}
public void run()
{
try
{
String line = inreadLine();
while (!lineequals(bye))
{
String msg = createMessage(line);
outprintln(msg);
line = inreadLine();
}
outprintln( See you bye! );
clientclose();
}
catch (IOException e)
{}
}
private String createMessage(String line)
{
xxxxxxxxx;
}
}
public static void main(String[] args) throws IOException
{
new Server();
}
}
这个程序监听端口并将接入交给CreateServerThread线程运行CreateServerThread线程接受输入并将输入回应客户直到客户输入bye线程结束我们可以在createMessage方法中对输入进行处理并产生结果然后把结果返回给客户
第三步 实现信息共享:在Socket上的实时交流
网络的伟大之一也是信息共享Server可以主动向所有Client广播消息同时Client也可以向其它Client发布消息下面看看如何开发一个可以实时传递消息的程序
设计原理
服务器端接受客户端的连接请求同时启动一个线程处理这个连接线程不停的读取客户端输入然后把输入加入队列中等候处理在线程启动的同时将线程加入队列中以便在需要的时候定位和取出
{源码}
import javaio*;
import *;
import javautil*;
import javalang*;
public class Server extends ServerSocket
{
private static ArrayList User_List = new ArrayList();
private static ArrayList Threader = new ArrayList();
private static LinkedList Message_Array = new LinkedList();
private static int Thread_Counter = ;
private static boolean isClear = true;
protected static final int SERVER_PORT = ;
protected FileOutputStream LOG_FILE = new FileOutputStream(d:/connectlog true);
public Server() throws FileNotFoundException IOException
{
super(SERVER_PORT);
new Broadcast();
//append connection log
Calendar now = CalendargetInstance();
String str = [ + nowgetTime()toString() + ] Accepted a connection\\;
byte[] tmp = strgetBytes();
LOG_FILEwrite(tmp);
try
{
while (true)
{
Socket socket = accept();
new CreateServerThread(socket);
}
}
finally
{
close();
}
}
public static void main(String[] args) throws IOException
{
new Server();
}
// Broadcast
class Broadcast extends Thread
{
public Broadcast()
{
start();
}
public void run()
{
while (true)
{
if (!isClear)
{
String tmp = (String)Message_ArraygetFirst();
for (int i = ; i < Threader.size(); i++)
{
CreateServerThread client = (CreateServerThread)Threader.get(i);