II 3.1 连接到服务器
II 3.1 连接到服务器

package socket; import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.Scanner; public class SocketTest
{
public static void main(String[] args) throws IOException
{
try(Socket s = new Socket("timr-A.tiemfreq.bldrdoc.gov", 13))
{
InputStream inStream = s.getInputStream();
Scanner in = new Scanner(inStream); while(in.hasNextLine())
{
String line = in.nextLine();
System.out.println(line);
}
}
} }
Socket s = new Socket("timr-A.tiemfreq.bldrdoc.gov", 13);
InputStream inStream = s.getInputStream();
第一行用来打开一个套接字,是一个抽象概念,用来负责启动程序内部和外部之间的通信。将远程地址和端口号传递给套接字的构造器,如果连接失败,会跑抛出一个UnknowHostException异常;如果存在其他问题,会抛出IOException异常。由于UnknowHostException是IOException的子类,所以在这里只需要捕获超类的异常即可。
一旦套接字打开,java.net.Socket类中的getInputStream方法就会返回一个InputStream对象,这个对象可以和其他任意流对象一样使用。一旦获取了这个流,程序就会将每一行打印出来,一直持续到流发送完毕。
Socket(String host, int port)
构建一个套接字,用来连接给定的主机和端口。
InputStream getInputStream()
获取可以从套接字中读取数据的流。
OutputStream getOutputStream()
向套接字写出数据的流。
3.1.1 套接字超时
从套接字读取信息的时候,在有数据可以访问之前,读操作将会被阻塞。如果此时主机不可达,那么应用会等到很长的时间,并且因为受低层操作系统的限制最终会导致超时。
对于不同的应用,应该确定合理的超时值。然后调用setSoTimeout方法设置这个超时值(单位:毫秒)
Socket s = new Socket(...);
s.setSoTimeout(10000);//10秒钟
如果已经为套接字设置了超时值,并且之后的读操作和写操作在没有完成之前就超过了时间限制,那么这些操作就会抛出SockTimeoutException异常,可以捕获这个异常,并且对超时做出反应。
try
{
InputStream in = s.getInputStream();
...
}catch(InterruptedIOException exception)
{
react to timeout
}
另外还有一个超时问题是必须解决的,下面的这个构造器:
Socket(String host, int port)
会一直无限期地阻塞下去,直到建立了主机之间的初始连接为止。
可以通过先构造一个无连接的套接字,然后再使用一个超时来进行连接的方法解决这个问题。
Socket s = new Socket();
s.connect(new InputSocketAddress(host, port), timeout);
用到的API如下:
Socket()
创建一个未被连接的套接字。
void connect(SocketAddress address)
将该套接字连接到指定的地址。
void connect(SocketAddress address, int timeoutInMilliseconds)
将套接字连接到指定的地址,如果在给定的时间里没有响应,则返回。
void setSoTimeout(int timeoutInMillseconds)
设置该套接字上读请求的阻塞时间。如果超出给定的时间,则抛出一个InterruptedIOException异常。
boolean isConnected()
如果套接字已经被连接,则返回true。
boolean isClosed()
如果套接字已经被关闭,则返回true。
3.1.2 因特网地址
通常不需要过多的考虑因特网地址的问题,它们是用一串数字表示的主机地址。一个因特网地址由4个字节组成(IPv6中是16个字节),比如132.3.2.123。但是需要在主机名和因特网地址之间进行转换,那么就可以使用InetAddress类。
静态的getByName方法可以返回代表某个主机的InetAddress对象。
InetAddress address = InetAddress.getByName("time-A.timefreq.bldrdoc.gov");
将会返回一个InetAddress对象,这个对象封装了一个4字节的序列:132.3.2.123。然后可以使用getAddress方法来访问这些字节:
byte[] addresses = InetAddress.getAllByName(host);
一些访问量比较大的主机名通常会对应多个因特网地址,以实现负载均衡,比如goole.com会对应多个因特网地址。当访问主机的时候,会随机的选取其中的一个。可以通过getAllByName来获取所有的主机:
InetAddress[] addresses = InetAddress.getAllByName(host);
有时候需要本地主机的地址,如果只是要求得到localhost的地址,那么总会得到地址127.0.0.1,但是其他程序无法使用这个地址来连接到这台机器上。此时可以使用静态的getLocalHost方法来得到本地主机的地址:
InetAddress address = InetAddress.getLocalHost();
package socket; import java.io.IOException;
import java.net.InetAddress; public class InetAddressTest
{
public static void main(String[] args) throws IOException
{
if(args.length > 0)
{
String host = args[0];
InetAddress[] address = InetAddress.getAllByName(host);
for(InetAddress a:address)
{
System.out.println(a);
}
}
else
{
InetAddress localHostAddress = InetAddress.getLocalHost();
System.out.println(localHostAddress);
}
}
}
3.2 实现服务器
实现一个简单的服务器,它可以向客户端发送信息,一旦启动服务器程序,它便会等待某个用户端连接到它的端口。
ServerSocket s = new ServerSocket(8189);
用于建立一个负责监控端口8189的服务器。
Socket incoming = s.accept();
用于高速程序不停等待,直到有客户端连接到这个端口,一旦有人通过网络发送了正确的连接请求,并以此连接到了端口上,该方法就会返回一个表示连接已经建立的Socket对象。
package socket; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner; public class EchoServer
{
public static void main(String[] args) throws IOException
{
try(ServerSocket s = new ServerSocket(8189))
{
try(Socket incoming = s.accept())
{
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream(); try(Scanner in = new Scanner(inStream))
{
PrintWriter out = new PrintWriter(outStream, true);
out.println("Hello! Enter BYE to exit."); boolean done = false;
while(!done && in.hasNextLine())
{
String line = in.nextLine();
out.println("Echo: " + line);
if(line.trim().equals("BYE"))
done = true;
}
}
}
}
} }
ServerSocket(int port)
创建一个监听端口的服务器套接字。
Socket accept()
等待连接。
该方法阻塞当前进程直到建立连接为止。这个方法返回一个Socket对象,程序可以通过这个对象与连接中的客户端进行通信。
void close()
关闭服务器套接字。
3.2.1 为多个客户端服务
服务器总是不间断地运行在服务器计算机上,来自整个因特网的用户希望同时使用服务器。前面介绍的服务器会拒绝多客户端连接,使得某个用户可能会因长时间地连接服务器而独占服务,所以需要使用多线程。
每当程序建立一个新的套接字连接,也就是调用accept的时候,将会启动一个新的线程来处理服务器和该客户端之间的连接,而主程序将立刻返回并等待下一个连接。
package socket; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner; public class ThreadEchoServer
{
public static void main(String[] args)
{
try
{
int i = 1;
ServerSocket s = new ServerSocket();
while(true)
{
Socket incoming = s.accept();
System.out.println("Spawning" + i);
Runnable r = new ThreadEchoHandler(incoming);
Thread t = new Thread(r);
t.start();
i++;
}
}catch(IOException e)
{
e.printStackTrace();
}
}
} class ThreadEchoHandler implements Runnable
{
private Socket incoming;
public ThreadEchoHandler(Socket i)
{
incoming = i;
} public void run()
{
try
{
try
{
//
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream(); Scanner in = new Scanner(inStream);
//
PrintWriter out = new PrintWriter(outStream, true);
out.println("Hello! Enter BYE to exit");
boolean done = false;
while(!done && in.hasNextLine())
{
String line = in.nextLine();
out.println("Echo: " + line);
if(line.trim().equals("BYE"))
done = true;
}
}
finally
{
incoming.close();
}
}catch(IOException e)
{
e.printStackTrace();
}
}
}
3.2.2 半关闭
半关闭(half-close)提供这样的一种能力:套接字连接的一端可以终止其输入,同时仍旧可以接收来自另一端的数据。
3.3 可中断套接字
3.4 获取Web数
3.4.1 URL和URI


II 3.1 连接到服务器的更多相关文章
- SQL Server 无法连接到服务器。SQL Server 复制需要有实际的服务器名称才能连接到服务器。请指定实际的服务器名称。
		异常处理汇总-数据库系列 http://www.cnblogs.com/dunitian/p/4522990.html SQL性能优化汇总篇:http://www.cnblogs.com/dunit ... 
- 解决Oracle SQL Developer无法连接远程服务器的问题
		在使用Oracle SQL Developer连接远程服务器的时候,出现如下的错误 在服务器本地是可以正常连接的.这个让人想起来,跟SQL Server的一些设计有些类似,服务器估计默认只在本地监听, ... 
- win7中 SQL server 2005无法连接到服务器,错误码:18456
		win7中 SQL server 2005无法连接到服务器,错误码:18456.. 数据库刚装完.我用Windows登陆 结果登陆不上去.. 选中SQL Server Management Stud ... 
- Redis集群~StackExchange.redis连接Sentinel服务器并订阅相关事件(原创)
		回到目录 对于redis-sentinel我在之前的文章中已经说过,它是一个仲裁者,当主master挂了后,它将在所有slave服务器中进行选举,选举的原则当然可以看它的官方文章,这与我们使用者没有什 ... 
- Strophe.js连接XMPP服务器Openfire、Tigase实现Web私聊、群聊(MUC)
		XMPP(Extensible Messaging and Presence Protocol)是一种网络即时通讯协议,它基于XML,具有很强的扩展性,被广泛使用在即时通讯软件.网络游戏聊天.Web聊 ... 
- 【FTP】C# System.Net.FtpClient库连接ftp服务器(上传文件)
		如果自己单枪匹马写一个连接ftp服务器代码那是相当恐怖的(socket通信),有一个评价较高的dll库可以供我们使用. 那就是System.Net.FtpClient,链接地址:https://net ... 
- 【FTP】C# System.Net.FtpClient库连接ftp服务器(下载文件)
		如果自己单枪匹马写一个连接ftp服务器代码那是相当恐怖的(socket通信),有一个评价较高的dll库可以供我们使用. 那就是System.Net.FtpClient,链接地址:https://net ... 
- 禁止Visual Studio启动时自动连接TFS服务器
		在默认设置情况下,Visual Studio启动时,会自动连接上次打开过的TFS服务器.这种设计能够提高开发人员的工作效率,避免每次手动连接TFS服务器. 但是在某些情景中,也会给人造成不必要的麻烦, ... 
- SSH如何通过公钥连接云服务器
		导读 通常我们连接远程服务器(linux)windows下通过putty或xshell等工具远程连接.linux下可以直接通过ssh命令连接.其实这两者都是一致的,都是通过ssh协议进行传输. 如果我 ... 
随机推荐
- 关于Quartz 2D绘图的简单使用
			Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境,Quartz 2D的API可以实现许多功能,如:基于路径的绘图.透明度.阴影.颜色管理.反锯齿.PDF文档生成和PDF元 ... 
- 对QP中RTC的理解
			1.概念 RTC(Run To Completion)是运行到完成为止的意思.在状态机中,从源状态到目标状态的转换动作要运行到完成. 从字面上来看,这个过程像是不可中断的,但实际并不是,这个过程可以被 ... 
- Python学习5——基本格式化输出
			整数的格式化输出 十进制.八进制.十六进制 num01 = 100 print("十进制输出:%d"%num01) print("八进制输出:%o"%num01 ... 
- keil5最新版安装与破解
			1. 下载链接: https://pan.baidu.com/s/1BIrhqmxWdHY7hvihE0Wd4A 密码: cp45 2. 解压缩后得到: 3. 运行mdk526.exe安装keil5. ... 
- vs2013工程配置
			1. 目标文件生成路径配置: 直接改在工程同级目录下 x64\debug目录下: 2. 调试工程路径配置: 命令-----参照物为工程 工作目录----参照物为运行程序 3. 拷贝工程: bat的写 ... 
- python基础的一些知识点
			ord 将字符转换为ASCIIchr 将ASCII转换为字符 元组不可修改,当只有一个元素时,要添加一个逗号集合不可修改,元素无序,不能重复 列表.元组.字典都是可迭代对象,就是可以遍历的对象多层循环 ... 
- 汇编指令lodsb和stosb、lodsd和stosd
			lodsb指令,将esi指向的地址处的数据取出来赋给AL寄存器,esi=esi+1: lodsw指令则取得是一个字. lodsd指令,取得是双字节,即mov eax,[esi],esi=esi+4: ... 
- Java基础—IO小结(二)缓冲流与其它流的使用
			一.缓冲流的使用 每个字节流都有对应的缓冲流: BufferedInputStream / BufferedOutputStream 构造器: 方法摘要与对应节点流类似 使用缓冲流实现文件复制:实际中 ... 
- AIDL 进程间通信的一个小小的总结
			需求 项目需要,将做好的项目作为一个服务提供给另一个公司.我们需要提供一个apk,所以设计到进程间交互,不得不了解一下AIDL了. 了解一下AIDL 之前准备面试的时候,或多或少的了解了一点AIDL, ... 
- BZOJ1083_繁忙的都市_KEY
			题目传送门 裸的最小生成树. code: /************************************************************** Problem: 1083 U ... 
