前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >II 3.1 连接到服务器

II 3.1 连接到服务器

作者头像
Mister24
发布于 2018-05-14 02:37:36
发布于 2018-05-14 02:37:36
1.3K00
代码可运行
举报
文章被收录于专栏:java初学java初学
运行总次数:0
代码可运行

II 3.1 连接到服务器

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);
			}
		}
	}

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Socket s = new Socket("timr-A.tiemfreq.bldrdoc.gov", 13);
InputStream inStream = s.getInputStream();

  第一行用来打开一个套接字,是一个抽象概念,用来负责启动程序内部和外部之间的通信。将远程地址和端口号传递给套接字的构造器,如果连接失败,会跑抛出一个UnknowHostException异常;如果存在其他问题,会抛出IOException异常。由于UnknowHostException是IOException的子类,所以在这里只需要捕获超类的异常即可。

  一旦套接字打开,java.net.Socket类中的getInputStream方法就会返回一个InputStream对象,这个对象可以和其他任意流对象一样使用。一旦获取了这个流,程序就会将每一行打印出来,一直持续到流发送完毕。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Socket(String host, int port)

  构建一个套接字,用来连接给定的主机和端口。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
InputStream getInputStream()

  获取可以从套接字中读取数据的流。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
OutputStream getOutputStream()

  向套接字写出数据的流。

3.1.1 套接字超时

从套接字读取信息的时候,在有数据可以访问之前,读操作将会被阻塞。如果此时主机不可达,那么应用会等到很长的时间,并且因为受低层操作系统的限制最终会导致超时。

  对于不同的应用,应该确定合理的超时值。然后调用setSoTimeout方法设置这个超时值(单位:毫秒)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Socket s = new Socket(...);
s.setSoTimeout(10000);//10秒钟

  如果已经为套接字设置了超时值,并且之后的读操作和写操作在没有完成之前就超过了时间限制,那么这些操作就会抛出SockTimeoutException异常,可以捕获这个异常,并且对超时做出反应。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try
{
    InputStream in = s.getInputStream();
    ...
}catch(InterruptedIOException exception)
{
    react to timeout
}

  另外还有一个超时问题是必须解决的,下面的这个构造器:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Socket(String host, int port)

  会一直无限期地阻塞下去,直到建立了主机之间的初始连接为止。

  可以通过先构造一个无连接的套接字,然后再使用一个超时来进行连接的方法解决这个问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Socket s = new Socket();
s.connect(new InputSocketAddress(host, port), timeout);

 用到的API如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Socket()

  创建一个未被连接的套接字。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void connect(SocketAddress address)

  将该套接字连接到指定的地址。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void connect(SocketAddress address, int timeoutInMilliseconds)

  将套接字连接到指定的地址,如果在给定的时间里没有响应,则返回。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void setSoTimeout(int timeoutInMillseconds)

  设置该套接字上读请求的阻塞时间。如果超出给定的时间,则抛出一个InterruptedIOException异常。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
boolean isConnected()

  如果套接字已经被连接,则返回true。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
boolean isClosed()

  如果套接字已经被关闭,则返回true。

3.1.2 因特网地址

通常不需要过多的考虑因特网地址的问题,它们是用一串数字表示的主机地址。一个因特网地址由4个字节组成(IPv6中是16个字节),比如132.3.2.123。但是需要在主机名和因特网地址之间进行转换,那么就可以使用InetAddress类。

  静态的getByName方法可以返回代表某个主机的InetAddress对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
InetAddress address = InetAddress.getByName("time-A.timefreq.bldrdoc.gov");

  将会返回一个InetAddress对象,这个对象封装了一个4字节的序列:132.3.2.123。然后可以使用getAddress方法来访问这些字节:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
byte[] addresses = InetAddress.getAllByName(host);

  一些访问量比较大的主机名通常会对应多个因特网地址,以实现负载均衡,比如goole.com会对应多个因特网地址。当访问主机的时候,会随机的选取其中的一个。可以通过getAllByName来获取所有的主机:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
InetAddress[] addresses = InetAddress.getAllByName(host);

  有时候需要本地主机的地址,如果只是要求得到localhost的地址,那么总会得到地址127.0.0.1,但是其他程序无法使用这个地址来连接到这台机器上。此时可以使用静态的getLocalHost方法来得到本地主机的地址:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
InetAddress address = InetAddress.getLocalHost();
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 实现服务器

实现一个简单的服务器,它可以向客户端发送信息,一旦启动服务器程序,它便会等待某个用户端连接到它的端口。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ServerSocket s = new ServerSocket(8189);

  用于建立一个负责监控端口8189的服务器。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Socket incoming = s.accept();

  用于高速程序不停等待,直到有客户端连接到这个端口,一旦有人通过网络发送了正确的连接请求,并以此连接到了端口上,该方法就会返回一个表示连接已经建立的Socket对象。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
					}
				}
			}
		}
	}

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ServerSocket(int port)

  创建一个监听端口的服务器套接字。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Socket accept()

  等待连接。

  该方法阻塞当前进程直到建立连接为止。这个方法返回一个Socket对象,程序可以通过这个对象与连接中的客户端进行通信。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void close()

  关闭服务器套接字。

3.2.1 为多个客户端服务

服务器总是不间断地运行在服务器计算机上,来自整个因特网的用户希望同时使用服务器。前面介绍的服务器会拒绝多客户端连接,使得某个用户可能会因长时间地连接服务器而独占服务,所以需要使用多线程。

  每当程序建立一个新的套接字连接,也就是调用accept的时候,将会启动一个新的线程来处理服务器和该客户端之间的连接,而主程序将立刻返回并等待下一个连接。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-03-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java网络知识之socket
当我们一个client连接一个套接字时,当前线程会被阻塞直到建立连接或者超时为止 同样的当通过套接字读写数据时,当前线程也会被阻塞或者直到超时 对于这种阻塞我们无法通过interrupt来解除阻塞 中断套接字
用户2436820
2018/09/05
5500
Java网络知识之socket
【Java_21】TCP、UDP
一、网络编程 1. 软件架构 ① B/S * Brower / Server ---> 浏览器 / 服务器 例如:淘宝网 ② C/S * Client / Server ---> 客户端 / 服务端 例如:QQ 2. 网络通信 ① 七层模型 * 数据链路层 ---> 物理层 ---> 网络层 ---> 传输层 ---> 会话层 ---> 表现层 ---> 应用层 ② 网络通信三要素 * 通信协议(TCP、UDP):去教室的方式 * i
用户8250147
2021/02/04
5480
手写一个 web 服务器!
作为后端开发人员,在实际的工作中我们会非常高频地使用到web服务器。而tomcat作为web服务器领域中举足轻重的一个web框架,又是不能不学习和了解的。
芋道源码
2020/12/18
1.6K1
Java SE 网络
第一行代码用于打开一个套接字,它是网络软件中的一个抽象概念,负责启动该程序内部和外部之间的通信。
honlyx
2023/03/14
8150
网络协议:一文搞懂Socket套接字
TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接。TCP 协议提供的是点对点的通信,每条 TCP 连接由两端的套接字唯一确定。可以理解为 TCP 连接两端的套接字来连起来就形成了管道,管道的两端或者说管道的端口就是 Socket 套接字。
栗筝i
2022/12/01
2.8K0
网络协议:一文搞懂Socket套接字
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
不像 UDP 有 DatagramPacket 是专门的“UDP 数据报”,TCP 没有专门的“TCP 数据报”
椰椰椰耶
2024/09/20
920
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
【JavaEE】——TCP回显服务器(万字长文超详细)
Socket是客户端Socket,或者服务端收到客户端accept的请求后返回的服务端Socket,不管是客户端还是服务端,都是建立连接以后,保存对端的信息,以及用来与对方接收和发送数据的
三三是该溜子
2024/12/30
1100
【JavaEE】——TCP回显服务器(万字长文超详细)
多线程TCP服务器
本文讲述了一个基于Java实现的TCP服务器和客户端的示例,通过多线程实现每连接发送一个图片,并提供了传输速度的提示。服务器端采用ServerSocket类实现,而客户端采用Socket类实现。客户端连接到服务器后,服务器会启动一个新的线程来处理每个客户端连接,客户端则在每个连接中发送一个图像文件。服务器端在处理每个连接时,读取文件并发送回客户端。传输速度提示通过在服务器端启动一个单独的线程来处理所有连接来实现。总体而言,该示例提供了一个简单的TCP通信框架,可以在基于Java的应用程序中使用。
GavinZhou
2018/01/02
1.7K0
多线程TCP服务器
Java 网络编程初探
Java 网络编程 网络编程 网络编程:进行服务器端与客户端编程的开发操作实现。 java.net:网络操作包 B/S结构: 浏览器/服务器模式(Browser/Server) 不在开发客户端代码 开发一套服务器端的程序代码 客户端利用浏览器进行访问 维护方便,安全性能低(使用公共的HTTP协议和80端口) C/S结构: 客户端/服务器模式(Client / Server) 需要编写两套程序: 客户端程序代码 服务器程序代码 C/S的开发非常的繁琐,因为开发人员需要维护两套程序
Mirror王宇阳
2020/11/10
4570
JAVA网络编程
一、osi网络7层架构 ip:网络唯一标识。(internet protocol address)网络互联协议地址。分为网络地址和主机地址。 port:端口号,每一个网络应用程序都需要一个以上的端口号。(1-65535)。1000以内的不要用。 osi7层架构
张哥编程
2024/12/13
780
Java-网络编程
哈喽!大家好,我是小简。今天开始学习《Java-网络编程》,此系列是我做的一个 “Java 从 0 到 1 ” 实验,给自己一年左右时间,按照我自己总结的 Java-学习路线,从 0 开始学 Java 知识,并不定期更新所学笔记,期待一年后的蜕变吧!
小简
2023/01/04
4780
Java-网络编程
【JavaEE初阶】网络编程
网络资源,其实就是在网络中可以获取的各种数据资源。 而所有的网络资源,都是通过网络编程来进行数据传输的。
xxxflower
2023/10/16
1940
【JavaEE初阶】网络编程
java---网络编程
socket(套接字) , 各种开发语言提供出来专门用于网络编程的API(接口),在传输层上的协议进行的编程tcp udp , 通过端口号来进行通信,实现点对点之间的通信 (服务端的Socket , 客户端的Socket)
用户10787181
2023/10/17
2680
java---网络编程
十六、网络编程【黑马JavaSE笔记】
UDP协议是一种不可靠的网路协议,它在通信的两端各建立一个Socket对象,但是这两个Socket只是发送,接收数据的对象 因此对于基于UDP协议的通信双方而言,没有所谓的客户端和服务器的概念
啵啵鱼
2022/11/23
5140
十六、网络编程【黑马JavaSE笔记】
【Tomcat】《How Tomcat Works》英文版GPT翻译(第一章)
This chapter explains how Java web servers work. A web server is also called a Hypertext Transfer Protocol (HTTP) server because it uses HTTP to communicate with its clients, which are usually web browsers. A Java-based web server uses two important classes: java.net.Socket and java.net.ServerSocket, and communications are done through HTTP messages. It is therefore natural to start this chapter with a discussion of HTTP and the two classes. Afterwards, it goes on to explain the simple web server application that accompanies this chapter.
阿东
2024/01/08
2840
【Tomcat】《How Tomcat Works》英文版GPT翻译(第一章)
Java从入门到精通十三(java网络编程)
前言:不在本文中详细说明网络通信(具体的准备有时间开一个网络专栏,具体按照Cisco Packet进行实验模拟说明。)
兰舟千帆
2022/07/16
1.9K0
Java从入门到精通十三(java网络编程)
Java 网络编程详解
TCP/IP (Transmission Control Protocol/Internet Protocol) 的简写,中文译名为传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是lnternet最基本的协议、Internet国际互联网络的基础,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的。
timerring
2023/05/11
8690
Java 网络编程详解
Java知识点——网络编程(如何网络编程和多线程实现tcp基础多文件交换功能)
网络通信协议是要求双方传递数据的计算机必须遵守的,按照对应的网络传输协议,才可以进入数据的交互和传递。
用户7073689
2020/03/17
8070
【Java网络编程】从套接字(Socket)概念到UDP与TCP套接字编程
Socket 套接字,是由系统提供用于网络通信的技术,是基于 TCP/IP 协议的网络通信的基本操作单元。基于Socket 套接字的网络程序开发就是网络编程。
小皮侠
2024/10/27
2400
【Java网络编程】从套接字(Socket)概念到UDP与TCP套接字编程
《Java-SE-第三十一章》之网络编程
&ebsp;&ebsp;当我们使用浏览器进行搜索时,浏览器会根据关键字搜索出视频,图片文本等资源,这些资源都属于网络资源。网络资源相比于本地资源来说更加的丰富多彩。而这些网络资源都需要通过网络编程来进行数据传输。
用户10517932
2023/10/07
2940
《Java-SE-第三十一章》之网络编程
相关推荐
Java网络知识之socket
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档