JavaSE——TCP协议网络编程(一)
实现客户端与服务端的连接:
- 创建TCP服务端的 ServerSocket
ServerSocket :此类实现服务器套接字。服务器套接字请求通过网络传入,基于该请求执行某些操作,然后可能向请求者返回结果。
其 accept()方法接受来自客户端的连接请求,并返回一个用于与Client 通信的Socket 对象。此后Server 的对象server 只要向该Socket 对象读写数据,就可以向远程的Client 读写数据。
下面是一个典型的创建Server端ServerSocket的过程。
ServerSocket server=null;
try {
server=new ServerSocket(4700);
//创建一个ServerSocket在端口4700监听客户请求
}catch(IOException e){
System.out.println("can not listen to :"+e);
}
Socket socket=null;
try {
socket=server.accept();
//accept()是一个阻塞的方法,一旦有客户请求,它就会返回一个Socket对象用于同客户进行交互
}catch(IOException e){
System.out.println("Error:"+e);
}
以上的程序是Server的典型工作模式,只不过在这里Server只能接收一个请求,接受完后Server就退出了。实际的应用中总是让它不停的循环接收,一旦有客户请求,Server总是会创建一个服务线程来服务新来的客户,而自己继续监听。程序中accept()是一个阻塞函数,所谓阻塞性方法就是说该方法被调用后,将等待客户的请求,直到有一个客户启动并请求连接到相同的端口,然后accept()返回一个对应于客户的socket。这时,客户方和服务方都建立了用于通信的socket,接下来就是由各个socket分别打开各自的输入/输出流。
ServerSocket 类的构造方法:
ServerSocket() 创建非绑定服务器套接字。 |
ServerSocket(int port) 创建绑定到特定端口的服务器套接字。 |
ServerSocket(int port, int backlog) 利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。 |
ServerSocket(int port, int backlog, InetAddress bindAddr) 使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。 |
ServerSocket 类的常用方法
Socket |
accept() 侦听并接受到此套接字的连接。 |
void |
bind(SocketAddress endpoint, int backlog) 将 ServerSocket 绑定到特定地址(IP 地址和端口号)。 |
void |
close() 关闭此套接字。 |
InetAddress |
getInetAddress() 返回此服务器套接字的本地地址。 |
boolean |
isBound() 返回 ServerSocket 的绑定状态。 |
boolean |
isClosed() 返回 ServerSocket 的关闭状态。 |
简要代码:
ServerSocket server = new ServerSocket( 有效端口号 );
Server client = server.accept(); // 在没有接收到客户端连接请求时, accept 属于堵塞状态,接收到后继续 //运行。
if(client!=null){
System.out.println("有客户端连接上来了");
}
2.TCP客户端的Socket
Socket 类:此类实现客户端套接字(“套接字”)套接字是两台机器间通信的端点。用于将应用程序和端口连接起来。不同的端口确定连接到服务器的哪项服务上。
创建一个Socket类之后,通过调用 Socket 的getInputStream 方法从服务程序获得输入流传送来的消息;通过调用 getOutputStream 方法获得输出流来发送消息。
创建 Socket:
下面是一个典型的创建客户端Socket的过程。
try{
Socket socket=new Socket("127.0.0.1",4700);
//127.0.0.1是TCP/IP协议中默认的本机地址
}catch(IOException e){
System.out.println("Error:"+e);
}
这是最简单的在客户端创建一个Socket的一个小程序段,也是使用Socket进行网络通讯的第一步,程序相当简单,在这里不作过多解释了。在后面的程序中会用到该小程序段。
注意,在选择端口时,必须小心。每一个端口提供一种特定的服务,只有给出正确的端口,才能获得相应的服务。0~1023的端口号为系统所保留,例如http服务的端口号为80,telnet服务的端口号为21,ftp服务的端口号为23, 所以我们在选择端口号时,最好选择一个大于1023的数以防止发生冲突。
在创建socket时如果发生错误,将产生IOException,在程序中必须对之作出处理。所以在创建Socket或ServerSocket是必须捕获或抛出例外。
常用的构造方法:
|
Socket() 通过系统默认类型的 SocketImpl 创建未连接套接字 |
|
Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。 |
|
Socket(InetAddress address, int port, InetAddress localAddr, int localPort) 创建一个套接字并将其连接到指定远程地址上的指定远程端口。 |
protected |
Socket(SocketImpl impl) 使用用户指定的 SocketImpl 创建一个未连接 Socket。 |
|
Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。 |
|
Socket(String host, int port, InetAddress localAddr, int localPort) 创建一个套接字并将其连接到指定远程主机上的指定远程端口。 |
其中address、host和port分别是双向连接中另一方的IP地址、主机名和端口号,stream指明socket是流socket还是数据报socket,localPort表示本地主机的端口号,localAddr和bindAddr是本地机器的地址(ServerSocket的主机地址),impl是socket的父类,既可以用来创建serverSocket又可以用来创Socket。count则表示服务端所能支持的最大连接数。例如:
Socket client = new Socket("127.0.01.", 80);
ServerSocket server = new ServerSocket(80);
常用的方法:
void |
bind(SocketAddress bindpoint) 将套接字绑定到本地地址。 |
void |
close() 关闭此套接字。 |
void |
connect(SocketAddress endpoint) 将此套接字连接到服务器。 |
void |
connect(SocketAddress endpoint, int timeout) 将此套接字连接到服务器,并指定一个超时值。 |
InetAddress |
getInetAddress() 返回套接字连接的地址。 |
InputStream |
getInputStream() 返回此套接字的输入流。 |
InetAddress |
getLocalAddress() 获取套接字绑定的本地地址。 |
OutputStream |
getOutputStream() 返回此套接字的输出流。 |
SocketAddress |
getRemoteSocketAddress() 返回此套接字连接的端点的地址,如果未连接则返回 null 。 |
boolean |
isBound() 返回套接字的绑定状态。 |
boolean |
isClosed() 返回套接字的关闭状态。 |
boolean |
isConnected() 返回套接字的连接状态。 |
boolean |
isInputShutdown() 返回是否关闭套接字连接的半读状态 (read-half)。 |
boolean |
isOutputShutdown() 返回是否关闭套接字连接的半写状态 (write-half)。 |
void |
shutdownInput() 此套接字的输入流置于“流的末尾”。 |
void |
shutdownOutput() 禁用此套接字的输出流。 |
String |
toString() 将此套接字转换为 String 。 |
简要代码:
Socket client = new Socket("127.0.0.0",9999); 服务端IP地址与端口号。
查询计算机的ip地址和端口号:
打开命令提示符,输入:
ipconfig/all (windows ip configuration 视窗操作系统ip配置)查看当前IP及电脑网络配置; 显示当前电脑ip相关所有信息,包括ip地址、网卡(mac)地址。
netstat -an ,查看当前所有连接端口; netstat(在内核中访问网络及相关信息的程序)显示网络连接、路由表和网络接口信息,可以让用户得知目前都有哪些网络连接正在运作。
package 网络编程; import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; public class Server{
public static void main(String[] args) {
try { ServerSocket server = new ServerSocket(9657);
Socket client = server.accept();
if(client!=null){
System.out.println("有客户端连接上来了");
server.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package 网络编程; import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException; public class Client { public static void main(String[] args) { try {
Socket client = new Socket("127.0.0.1",9657);
client.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
output:有客户端连接上来了。
此段服务端代码存在问题,客户端与服务端建立连接之后服务会自动关闭,不能继续接受多个客户端的请求。可以加上一个 while 循环,使服务端接受一个客户端的请求后又回到 accept() 的接受状态。
3.ServerSocket 类与Socket 类的不同用法:
ServerSocket类:
创建一个ServerSocket类,同时在运行该语句的计算机的指定端口处建立一个监听服务,如:
ServerSocket MyListener = new ServerSocket(600);
这里指定提供监听服务的端口是600,一台计算机可以同时提供多个服务,这些不同的服务之间通过端口号来区别,不同的端口号上提供不同的服务。为了随时监听可能的Client请求,执行如下的语句:
Socket LinkSocket = MyListener.accept();
该语句调用了ServerSocket对象的accept()方法,这个方法的执行将使Server端的程序处于等待状态,程序将一直阻塞直到捕捉到一个来自Client端的请求,并返回一个用于与该Client通信的Socket对象Link-Socket。此后Server程序只要向这个Socket对象读写数据,就可以实现向远端的Client读写数据。结束监听时,关闭ServerSocket对象:
Mylistener.close();
Socket 类:
当Client程序需要从Server端获取信息及其他服务时,应创建一个Socket对象:
Socket socket=new Socket(“ServerComputerName”,600);
Socket类的构造函数有两个参数,第一个参数是欲连接到的Server计算机的主机地址,第二个参数是该Server机上提供服务的端口号。
Socket对象建立成功之后,就可以在Client和Server之间建立一个连接,并通过这个连接在两个端点之间传递数据。利用Socket类的方法getOutputStream()和getInputStream()分别获得向Socket读写数据的输入/输出流,最后将从Server端读取的数据重新返还到Server端。
当Server和Client端的通信结束时,可以调用Socket类的close()方法关闭Socket,拆除连接。
ServerSocket 一般仅用于设置端口号和监听,真正进行通信的是服务器端的Socket与客户端的Socket,在ServerSocket 进行accept之后,就将主动权转让了。
JavaSE——TCP协议网络编程(一)的更多相关文章
- JavaSE——TCP协议网络编程(二)
1.Java网络编程与多线程的综合应用: 类Socket提供了方法getInputStream ()和getOutStream()来得到对应的输入/输出流以进行读/写操作,这两个方法分别返回Input ...
- Qt基于tcp协议网络编程
基于Qt网络编程: 基于tcp协议 c/s模式编程 所需要的类:QTcpServer QTcpSocket 利用qt基于tcp协议编写c/s模式程序: 两个类中的信号: QTcpServer : ne ...
- JavaSE——UDP协议网络编程(一)
UDP协议基础: UDP协议是英文UserDatagramProtocol的缩写,即用户数据报协议,主要用来支持那些需要在计算机之间传输数据的网络应用.包括网络视频会议系统在内的众多的客户/服务器模式 ...
- JavaSE——UDP协议网络编程(二)
在 UDP 网络编程中,发送方与接收方没有建立联系,没有明显的服务器端和客户端的区别. 类 DatagramSocket: 此类表示用来发送和接收数据报包的套接字. 主要的构造方法: Datagram ...
- 基于TCP协议网络编程
1.TCP/IP是一种可靠的网络协议,它在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路: 一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路来进行通信: 2.Java对基 ...
- Java SE ——TCP协议网络编程(三)
之前的代码中关闭了 socket 对象的输入流与输出流,但并没有关闭掉socket 对象,会造成服务器资源的浪费,应通过调用 socket 的 close() 方法来关闭当前的socket 对象. 因 ...
- TCP/IP协议网络编程以及UDP和TCP之传输协议
1.什么是TCP/IP协议? 网络编程协议有很多,目前应用最广泛的是TCP/IP协议(Transmission Control Protocal/Internet Protoal 传输控制协议/英特网 ...
- (1)线程的同步机制 (2)网络编程的常识 (3)基于tcp协议的编程模型
1.线程的同步机制(重点)1.1 基本概念 当多个线程同时访问同一种共享资源时可能会造成数据的覆盖和不一致等问题,此时就需要对线程之间进行协调和通信,该方式就叫线程的同步机制. 如: 2003年左右 ...
- (1)网络编程的常识 (2)基于tcp协议的编程模型 (3)tcp协议和udp协议的比较 (4)基于udp协议的编程模型
1.网络编程的常识 目前主流的网络通讯软件有:微信.QQ.YY.陌陌.探探.飞信.阿里旺旺.... 在吗? 1.1 七层网络模型(熟悉) 为了保证数据传递的可靠安全等等,ISO(国际标准委员会组织)将 ...
随机推荐
- One-hot数据处理
机器学习 数据预处理之独热编码(One-Hot Encoding)(转) 问题由来 在很多机器学习任务中,特征并不总是连续值,而有可能是分类值. 例如,考虑一下的三个特征: ["male&q ...
- PHP:使用Zend对源码加密、Zend Guard安装以及Zend Guard Run-time support missing的解决方法
Zend Guard是目前市面上最成熟的PHP源码加密产品了.刚好需要对自己的产品进行加密,折腾了一晚上,终于搞定,将碰到的问题及解决方法记录下来,方便日后需要,也可以帮助其他人.我使用的是Wamps ...
- url最后的“/”是什么作用
多了个尾巴 有时候,当你尝试在地址栏输入https://123/demo的时候,会发现浏览器会重定向到https://123/demo/这个地址,也就是多了个/,发生了重定向.有图为证: 上面这个图是 ...
- Vue.js之组件(component)
从结构上看,组件之于实例,就好比轮子之于汽车.从属性和方法来看,组件有实例的大部分方法,如果Vue实例是孙悟空,组件就好比实例的一个毫毛,变化多端却为Vue实例所用. 目录: 组件的注册 is的作用 ...
- eclipse maven jdk全局设置
<profile> <id>jdk-1.8</id> <activation> <activeByDefault>true</acti ...
- editplus tag
#T=HTML<!DOCTYPE html><html lang="zh-CN"><head><meta content="te ...
- 31-hadoop-hbase-mapreduce操作hbase
有一些大的文件,需要存入HBase中,其思想是先把文件传到HDFS上,利用map阶段读取<key,value>对,可在reduce把这些键值对上传到HBase中. HbaseMapper: ...
- 《Netty权威指南》(三)Netty 入门应用
Netty 服务端 Netty 客户端
- DataSet 多表关系
protected void Page_Load(object sender, EventArgs e) { string connectionString = @"Data Source= ...
- jdbc mysql driver 6.0.2
url = jdbc:mysql://localhost:3306/hibernate?useUnicode=true&characterEncoding=UTF-8&useLegac ...