|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
C++编译的是本地码,优点是启动快,而且可以精确控制资源因此可以开发很高效的程序.缺点是编程麻烦,而且容易留下安全隐患.跨平台靠源代码在各个平台间分别编译(一处编写到处编译)编程ServerSocket类
因为SSClient利用了流套接字,以是服务程序也要利用流套接字。这就要创立一个ServerSocket对象,ServerSocket有几个机关函数,最复杂的是ServerSocket(intport),当利用ServerSocket(intport)创立一个ServerSocket对象,port参数传送端标语,这个端口就是服务器监听毗连哀求的端口,假如在这时候呈现毛病将抛出IOException非常对象,不然将创立ServerSocket对象并入手下手筹办吸收毗连哀求。
接上去服务程序进进无穷轮回当中,无穷轮回从挪用ServerSocket的accept()办法入手下手,在挪用入手下手后accept()办法将招致挪用线程堵塞直到毗连创建。在创建毗连后accept()前往一个比来创立的Socket对象,该Socket对象绑定了客户程序的IP地点或端标语。
因为存在单个服务程序与多个客户程序通信的大概,以是服务程序呼应客户程序不该该花良多工夫,不然客户程序在失掉服务前有大概花良多工夫来守候通信的创建,但是服务程序和客户程序的会话有多是很长的(这与德律风相似),因而为加速对客户程序毗连哀求的呼应,典范的办法是服务器主机运转一个背景线程,这个背景线程处置服务程序和客户程序的通信。
为了树模我们在下面谈到的慨念并完成SSClient程序,上面我们创立一个SSServer程序,程序将创立一个ServerSocket对象来监听端口10000的毗连哀求,假如乐成服务程序将守候毗连输出,入手下手一个线程处置毗连,并呼应来自客户程序的命令。上面就是这段程序的代码:
Listing3:SSServer.java
//SSServer.java
importjava.io.*;
importjava.net.*;
importjava.util.*;
classSSServer
{
publicstaticvoidmain(String[]args)throwsIOException
{
System.out.println("Serverstarting...
");
//Createaserversocketthatlistensforincomingconnection
//requestsonport10000.
ServerSocketserver=newServerSocket(10000);
while(true)
{
//Listenforincomingconnectionrequestsfromclient
//programs,establishaconnection,andreturnaSocket
//objectthatrepresentsthisconnection.
Sockets=server.accept();
System.out.println("AcceptingConnection...
");
//Startathreadtohandletheconnection.
newServerThread(s).start();
}
}
}
classServerThreadextendsThread
{
privateSockets;
ServerThread(Sockets)
{
this.s=s;
}
publicvoidrun()
{
BufferedReaderbr=null;
PrintWriterpw=null;
try
{
//Createaninputstreamreaderthatchainstothesockets
//byte-orientedinputstream.Theinputstreamreader
//convertsbytesreadfromthesockettocharacters.The
//conversionisbasedontheplatformsdefaultcharacter
//set.
InputStreamReaderisr;
isr=newInputStreamReader(s.getInputStream());
//Createabufferedreaderthatchainstotheinputstream
//reader.Thebufferedreadersuppliesaconvenientmethod
//forreadingentirelinesoftext.
br=newBufferedReader(isr);
//Createaprintwriterthatchainstothesocketsbyte-
//orientedoutputstream.Theprintwritercreatesan
//intermediateoutputstreamwriterthatconverts
//characterssenttothesockettobytes.Theconversion
//isbasedontheplatformsdefaultcharacterset.
pw=newPrintWriter(s.getOutputStream(),true);
//Createacalendarthatmakesitpossibletoobtaindate
//andtimeinformation.
Calendarc=Calendar.getInstance();
//Becausetheclientprogrammaysendmultiplecommands,a
//loopisrequired.Keeploopinguntiltheclienteither
//explicitlyrequeststerminationbysendingacommand
//beginningwithlettersBYEorimplicitlyrequests
//terminationbyclosingitsoutputstream.
do
{
//Obtaintheclientprogramsnextcommand.
Stringcmd=br.readLine();
//Exitifclientprogramhascloseditsoutputstream.
if(cmd==null)
break;
//Convertcommandtouppercase,foreaseofcomparison.
cmd=cmd.toUpperCase();
//IfclientprogramsendsBYEcommand,terminate.
if(cmd.startsWith("BYE"))
break;
//IfclientprogramsendsDATEorTIMEcommand,return
//currentdate/timetotheclientprogram.
if(cmd.startsWith("DATE")||cmd.startsWith("TIME"))
pw.println(c.getTime().toString());
//IfclientprogramsendsDOM(DayOfMonth)command,
//returncurrentdayofmonthtotheclientprogram.
if(cmd.startsWith("DOM"))
pw.println(""+c.get(Calendar.DAY_OF_MONTH));
//IfclientprogramsendsDOW(DayOfWeek)command,
//returncurrentweekday(asastring)totheclient
//program.
if(cmd.startsWith("DOW"))
switch(c.get(Calendar.DAY_OF_WEEK))
{
caseCalendar.SUNDAY:pw.println("SUNDAY");
break;
caseCalendar.MONDAY:pw.println("MONDAY");
break;
caseCalendar.TUESDAY:pw.println("TUESDAY");
break;
caseCalendar.WEDNESDAY:pw.println("WEDNESDAY");
break;
caseCalendar.THURSDAY:pw.println("THURSDAY");
break;
caseCalendar.FRIDAY:pw.println("FRIDAY");
break;
caseCalendar.SATURDAY:pw.println("SATURDAY");
}
//IfclientprogramsendsDOY(DayofYear)command,
//returncurrentdayofyeartotheclientprogram.
if(cmd.startsWith("DOY"))
pw.println(""+c.get(Calendar.DAY_OF_YEAR));
//IfclientprogramsendsPAUSEcommand,sleepforthree
//seconds.
if(cmd.startsWith("PAUSE"))
try
{
Thread.sleep(3000);
}
catch(InterruptedExceptione)
{
}
}
while(true);
{
catch(IOExceptione)
{
System.out.println(e.toString());
}
finally
{
System.out.println("ClosingConnection...
");
try
{
if(br!=null)
br.close();
if(pw!=null)
pw.close();
if(s!=null)
s.close();
}
catch(IOExceptione)
{
}
}
}
}
运转这段程序将失掉上面的输入:
Serverstarting...
AcceptingConnection...
ClosingConnection...
SSServer的源代码声了然一对类:SSServer和ServerThread;SSServer的main()办法创立了一个ServerSocket对象来监听端口10000上的毗连哀求,假如乐成,SSServer进进一个无穷轮回中,瓜代挪用ServerSocket的accept()办法来守候毗连哀求,同时启动背景线程处置毗连(accept()前往的哀求)。线程由ServerThread承继的start()办法入手下手,并实行ServerThread的run()办法中的代码。
一旦run()办法运转,线程将创立BufferedReader,PrintWriter和Calendar对象并进进一个轮回,这个轮回由读(经由过程BufferedReader的readLine())来自客户程序的一行文本入手下手,文本(命令)存储在cmd援用的string对象中,假如客户程序过早的封闭输入流,会产生甚么呢?谜底是:cmd将得不到赋值。
注重必需思索到这类情形:在服务程序正在读输出流时,客户程序封闭了输入流,假如没有对这类情形举行处置,那末程序将发生非常。
一旦编译了SSServer的源代码,经由过程输出JavaSSServer来运转程序,在入手下手运转SSServer后,就能够运转一个或多个SSClient程序。
首先java功能强大的背后是其复杂性,就拿web来说,当今流行的框架有很多,什么struts,spring,jQuery等等,而这无疑增加了java的复杂性。 |
|