当前位置 : 主页 > 编程语言 > java >

Java网络编程之客户端中的Socket

来源:互联网 收集:自由互联 发布时间:2022-07-14
Socket Socket是两个主机之间的连接,它有下面7种基本操作: 连接到远程主机 发送数据 接受数据 关闭连接 绑定端口 监听输入数据 在绑定的端口上接受远程机器的连接 前面4中操作是客


Socket

Socket是两个主机之间的连接,它有下面7种基本操作:

  • 连接到远程主机
  • 发送数据
  • 接受数据
  • 关闭连接
  • 绑定端口
  • 监听输入数据
  • 在绑定的端口上接受远程机器的连接

前面4中操作是客户端和服务端共有的,后面3种只有服务端才需要(定义在ServerSocket类中)。

从Server读取数据

public void readFromTimeServer() throws IOException {
//不是创建对象,而是建立连接
try (Socket socket = new Socket("time.nist.gov",13)){
socket.setSoTimeout(15000);//设置超时时间15s
InputStream in = socket.getInputStream();
StringBuilder time = new StringBuilder();
InputStreamReader reader = new InputStreamReader(in,"ASCII");
for (int c = reader.read();c!= -1;c=reader.read()){
time.append((char)c);
}
System.out.println(time);
}
}

设置超时时间是一个很好的习惯。

写数据到Server

@Test
public void writeToServer() throws IOException {
Socket socket = new Socket("dict.org", 2628);
socket.setSoTimeout(15000);
OutputStream out = socket.getOutputStream();
Writer writer = new OutputStreamWriter(out, "UTF-8");
writer.write("DEFINE eng-lat gold\r\n");
writer.flush();
}

构造和连接Socket

基本构造函数

public Socket(String host, int port) throws UnknownHostException, IOException
public Socket(InetAddress host, int port) throws

在构造函数返回之前,一条与远端的网络连接已经被建立完成。
可以利用构造函数的这个特性来检查有效的端口。

String host = "localhost";
for (int i = 1; i < 1024; i++) {
try {
Socket s = new Socket(host, i);
System.out.println("There is a server on port " + i + " of "
+ host);
s.close();
} catch (UnknownHostException ex) {
System.err.println(ex);
break;
} catch

还有3个构造函数创建的是无连接的socket

public Socket()
public Socket(Proxy proxy)
protected Socket(SocketImpl impl)

SocketAddress

SocketAddress代表着连接的终端地址。
SocketAddress可以用来保存IP地址和端口这种信息,可以重用与构造新的Socket。

public SocketAddress getRemoteSocketAddress()
public SocketAddress getLocalSocketAddress()

这两个方法分别用来获取一个连接的远端地址和本地地址。

Socket socket = new Socket("www.yahoo.com", 80);
SocketAddress yahoo = socket.getRemoteSocketAddress();
socket.close();
//Later, you could reconnect to Yahoo! using this address:
Socket socket2 = new Socket();
socket2.connect(yahoo);

获取Socket的相关信息

Socket的下面这几个属性可以通过相应的Get方法获取:
• Remote address
• Remote port
• Local address
• Local port

public InetAddress getInetAddress()
public int getPort()
public InetAddress getLocalAddress()
public int getLocalPort()

但是没有Set方法,因为这些属性会在连接建立成功的时候设置。

​​getInetAddress()​​​和​​getPort()​​​方法告诉你Socket连接到的远程主机和端口;
​​​getLocalAddress()​​​和​​getLocalPort()​​方法告诉你Socket连接源端的网卡(network interface)和端口。

与远程端口不同,它通常是“知名端口”,已经由一个标准委员会预先指定;而本地端口通常由系统在运行时从可用的未使用的端口中选择。 这样,同一个系统中多个不同的客户端可以同时访问相同的服务。 本地端口已经和本地主机的IP地址一起嵌入到输出IP数据包,因此服务器可以发送数据到客户端的正确端口。

"www.baidu.com,www.qq.com".split(",");
for (String host : args) {
try {
Socket theSocket = new Socket(host, 80);
System.out.println("Connected to " + theSocket.getInetAddress()
+ " on port " + theSocket.getPort() + " from port "
+ theSocket.getLocalPort() + " of "
+ theSocket.getLocalAddress());
} catch (UnknownHostException ex) {
System.err.println("I can't find " + host);
} catch (SocketException ex) {
System.err.println("Could not connect to " + host);
} catch (IOException ex) {
System.err.println(ex);

打印:

Connected to www.baidu.com/14.215.177.38 on port 80 from port 32416 of /192.168.5.46
Connected to www.qq.com/59.37.96.63 on port 80 from port 32417 of /192.168.5.46

有个方法叫做​​isConnected()​​,它用来判断是否连接过,无法判断现在是否是连接的。如果想判断现在是否是连接状态,可通过下面的代码:

boolean connected = socket.isConnected() && ! socket.isClosed();

Socket中的异常

public class BindException extends SocketException
public class ConnectException extends SocketException
public class NoRouteToHostException extends SocketException

在端口被占用或无访问端口的权限时会抛出BindException;
当客户端尝试连接到远端时,如果远端正忙或者没有监听那个端口,那么会抛出ConnectException;
如果连接超时会抛出NoRouteToHostException;


【文章转自:游戏服务器 http://www.558idc.com/yz.html 复制请保留原URL】
上一篇:非递归归并排序详细分析
下一篇:没有了
网友评论