Java网络编程之简单的服务端客户端应用实例
本文实例讲述了java网络编程之简单的服务端客户端应用。分享给大家供大家参考。具体如下:
在java中,我们使用java.net.socket及其相关类来完成有关网络的相关功能。socket类非常简单易用,因为java技术隐藏了建立网络连接和通过连接发送数据的复杂过程。下面所说的内容只适用于tcp协议。
一、连接到服务器
我们可以使用socket类的构造函数来打开一个套接字,如
socket sk = new socket("210.0.235.14",13);
其中,210.0.235.14是一个点分十进制的string对象,表示目的主机的ip地址(或主机名), 13表示指定连接目标主机的13端口。这里的210.0.235.14是位于香港的一个授时服务器,授时服务器默认的端口一般都为13.
注意,在成功连接到服务器之前,程序会阻塞。
接下来可以使用socket类的getinputstream()方法来得到一个inputstream对象,通过这个对象就可以获取到目标主机给我们发过来的信息:
inputstream instream = sk.getinputstream();
同理,要向目标主机发送数据,则可以调用getoutputstream()方法来获取一个输出流对象。
下面的例子功能是连接授时服务器,并将返回的信息打印到标准输出中:
try { socket sk = new socket("210.0.235.14",13); sk.setsotimeout(3000); inputstream instream = sk.getinputstream(); //得到输入流对象 scanner sc = new scanner(instream); //将数据打印到控制台 while(sc.hasnextline()) { string str = sc.nextline(); system.out.println("output : " + str); } sk.close(); } catch(sockettimeoutexception e) //超时异常 { system.out.println("time out!"); } catch(exception e) { e.printstacktrace(); }
代码中setsotimeout()方法可以设置超时时间,即如果超过了设定时间还没有完成读写操作,则会抛出sockettimeoutexception,可以通过捕获这个异常来关闭连接。
另外还有一个超时问题是必须要解决的,就是这个socket类的构造函数
new socket(host,port);
会一直无限地阻塞下去,直到成功建立了到目标主机的连接为止。这当然不是我们所希望的。我们可以通过如下调用方式解决此问题:
socket sk = new socker(); sk.connect(new inetsocketaddress(host,port),2000); //设置超时时间为2秒
二、获取主机地址
inetaddress类的静态方法getbyname(hostname)可以返回代表了某个主机地址的inetaddress对象,这个对象封闭了一个4字节的序列,即主机的ip地址。然后再调用gethostaddress()方法返回一个表示ip地址的string对象.
一些访问量大的主机名通常会对应着多个ip地址以实现负载均衡。我们可以调用getallbyname()方法来获得所有主机地址,该方法返回一个inetaddress对象的数组。
下面是一个简单的小程序,实现的功能是,如果不在命令行中设置参数,就打印出本地的ip地址,如果指定了主机名,则打印出该主机所有的ip地址:
package cls; import java.net.*; public class showip { public static void main(string[] args) { try { if(args.length > 0) { string hostname = args[0]; //主机名 inetaddress[] addr = inetaddress.getallbyname(hostname); //得到该主机的所有地址 //打印输出至控制台 for(inetaddress address : addr) { system.out.println(address.gethostaddress()); } } else { system.out.println(inetaddress.getlocalhost().gethostaddress()); } } catch(exception e) { e.printstacktrace(); } } }
三、服务器端程序
服务器端应用程序使用serversocket类来创建套接字,并钭其绑定至本地端口中,如
serversocket sock = new serversocker(8000);
sock.accept()方法让程序不停地等待连接,该方法只有当有客户端连接时才会返回一个代表了新连接的socket对象,即该方法会发生阻塞。
这里一般要为每个连接新开启一个线程为其服务。
下面是一个完整的例子,服务端在8400端口处等待连接,每当连接到来时,新开一个线程为其服务,并将连接信息写入的日志文件中:
package cls; import java.io.*; import java.net.*; import java.util.*; public class serverdemo { /** * @param args */ public static void main(string[] args) { try { //serversocket servsocket = new serversocket(8000); serversocket servsocket = new serversocket(8400); int amount = 0; while(true) { socket client = servsocket.accept(); ++amount; date time = new date(); string prompt = time.tostring() + ": 第" + amount + "个用户 " + client.getinetaddress().gethostaddress() + " 已连接\n"; system.out.print(prompt); //在控制台输出信息 serverdemo.writelog(prompt); //写入到文件中 //start a new thread thread th = new thread(new servthread(client,amount)); th.start(); } } catch(exception e) { e.printstacktrace(); } } //写入日志文件 public static void writelog(string str) { file logfile = new file("server-log.txt"); try { filewriter out = new filewriter(logfile,true); out.append(str); out.close(); } catch(exception e) { e.printstacktrace(); } } } /* * 服务线程类 */ class servthread implements runnable { private socket client; private int ix; public servthread(socket soc,int ix) { client = soc; this.ix = ix; } public void run() { try { inputstream instream = client.getinputstream(); outputstream outstream = client.getoutputstream(); scanner recv = new scanner(instream); printwriter send = new printwriter(outstream,true); send.println("欢迎~随便聊几句吧![输入'bye'关闭联接]"); while(recv.hasnextline()) { string str = recv.nextline(); if(str.equals("bye")) { send.println("see you later ~ ^-^"); break; } send.println("这是个测试程序,现在还没有什么功能哦"); } date time = new date(); string prompt = time.tostring() + ": 第" + ix + "个用户 " + client.getinetaddress().gethostaddress() + " 已断开连接\n"; system.out.print(prompt); serverdemo.writelog(prompt); //写入到文件中 client.close(); } catch(exception e) { e.printstacktrace(); } } }
这个程序已经被放到了服务器上,大家可以使用telnet youthol.tk 8400 命令来体验一下这个程序的运行结果
希望本文所述对大家的java程序设计有所帮助。
上一篇: Java中对象的销毁方法分析