socket通讯编程

这一块属于网络编程,主要是学习TCP/IP四层的网络体系结构,学习TCP编程和UDP编程。

java.net中


一.IP地址:

1.  IPV4:Inet4Address

IPV6 :Inet6Address

都继承与InetAddress类,是java对IP地址的封装,其实例对象包括ip地址和主机名。

2. InetAddress的构造方法不是共有的,要通过static方法获取实例对象:(获取IP地址)

static InetAddress[] getAllByName(String host)

static InetAddress  getByAddress(byte[]  addr) 

static InetAddress getByAddress(String host,byte[]  addr) 

static InetAddress getByName(String host)   //传入目标主机的名字,如传入网站网址

static InetAddress getLocalHost()   //返回本地ip地址

举个栗子:

socket通讯编程_第1张图片

返回本地ip地址:

socket通讯编程_第2张图片

二、流

1.输出流:基类是java.io.OutputStream  抽象类(向流中写数据)

public abstract void write(int b) throws IOException;  //将指定字节写入输出流,只写入低8位,高位抛弃

public void write(byte[] b) throws IOException;  //将byte数组所有字节写入输出流

(=write(b,0,b.length))

public void write(byte[] b,int off,int len) throws IOException;  //将byte数组指定字节写入输出流

public void flush() throws IOException //将输出流缓存的所有字节写向预期目标

public void close() throws IOException  //关闭输入流,释放资源


2.输入流:基类是java.io.InputStream  抽象类(从输入流读取数据)

public abstract int read() throws IOException  //从输入流读取数据下一个字节,到达流末尾返回-1

public int read(byte[] b) throws IOException  //从输入流读取一定数量的字节

public int read(byte[] b,int off,int len) throws IOException  //从输入流读取一定数量的字节

public long skip(long n) throws  IOException  //跳过输入流的n个字节,并将这些字节丢弃

public int available()  throws IOException  //获取输入流中可供读取或跳过的字节数

public void close()  throws IOException  //关闭输入流,释放资源


3.输出流处理工具:java.io.Writer  (抽象类,向输出流写入...)

常用子类是PrinterWriter(有write()、print()、println() )

public void write(int c)  throws IOException;  

public void write(char[] cbuf)  throws IOException ;

public abstract void write(char[] cbuf,int off,int len)  throws IOException  

public void write(String s)  throws IOException  

public void write(String s,int off,int len)  throws IOException  


4.输入流处理工具  java.io.Reader (抽象类) 

public int read()  throws IOException 

public int read(char[] cbuf)  throws IOException 

public abstract void read(char[] cbuf,int off,int len)  throws IOException  

public int read(CharBuffer target)  throws IOException 

常用子类有InputStreamReader、BufferedReader:(常配合使用)

通常使用:BufferedReader in =new BufferedReader(new InputStreamReader(System.in))

即:InputStream  -->  InputStreamReader  -->  BufferedReader


5.套接字

流套接字:Socket  ServerSocket

数据报套接字: DatagramSocket  MulticastSocket


二、TCP编程(面向字节流,面向连接,可靠,面向连接,可以单播也可以广播)

1.Socket(建立网络连接时,两端都产生一个socket实例,可操作这个实例完成会话)

构造方法:

public Socket(String host,int port)  //指定主机,指定端口

public Socket(InetAddress address, int port , InetAddress localAddr, int localPort)  //本地地址和端口,目的地的地址和端口

public Socket()

工具方法:(用于处理网络会话)

public InputStream getInputStream()  throws IOException  //返回程序中套接字所能读取的输入流

public OutputStream getOutputStream()  throws IOException   //返回程序中套接字的输出流

public void close()  throws IOException 

connect(SocketAddress endpoint)  //连接到远程服务器

getInetAddress()  //获取远处服务器地址


2.ServerSocket(服务器端)

实现服务器套接字,等待请求通过网络传入,基于该请求执行某些操作,然后可能向请求者返回结果。

数据报中传输的数据是以字节数组的形式存储,所以当定义了字符串之后,要转换为字节数组  byte[]  buf=s.getBytes();

构造方法:

 public ServerSocket()  throws IOException  //创造服务器套接字

 public ServerSocket(int port )  throws IOException  //指定监听端口(常用)

public ServerSocket(int port ,int backlog)  throws IOException //指定监听端口和接受的最大连接数

public ServerSocket(int port ,int backlog,InetAddress bindAddr)  throws IOException //指定监听端口、地址和接受的最大连接数

工具方法:

public Socket accept()  throws IOException   //该方法一直处于阻塞状态,直到有新的连接接入,建立连接后,该方法会返回一个套接字,用于处理客户端请求以及服务端响应

public void setSoTimeout(int timeout) throws SocketException  //设置最大阻塞时间,超过就会抛出异常

public void close() throws IOException  //关闭服务器套接字


3.一对一通信

举个栗子:客户端向服务端发送连接请求,链接建立后,客户端向服务端发送一个简单的请求,服务端接收这个请求,根据请求内容做相应处理,并返回处理结果。

运行时,先运行服务器端。否则客户端会因为无法创建连接而抛出异常。

关闭的时候一般先关闭工具,最后再关闭socket和 ServerSocket

server:要serversocket 和socket实例

socket通讯编程_第3张图片
server

Client:只要socket实例

socket通讯编程_第4张图片
Client

4.一对多通信

要实现一个服务器给多个客户提供服务,用多线程实现多客户机制。服务器总是在指定端口监听是否有客户请求,有则服务器启动一个专门的服务线程来响应该客户的请求,而服务器在启动完线程后又进入监听状态,等待下一个客户。

服务端定义两个类,一个Server1负责监听连接和线程分配,一个SocketHandler负责套接字及流的处理。客户端不变。

先执行服务器类,再执行客户类。

Server1:监听连接和线程分配

socket通讯编程_第5张图片

SocketHandler:负责套接字及流的处理

socket通讯编程_第6张图片

运行结果:

socket通讯编程_第7张图片


三、UDP编程(面向报文,无连接,不可靠的,只能单播,不能单播)

1.DatagramPacket:(表示数据报包)

一个数据报文=一个DatagramPacket实例

发送信息,创建一个数据报文(一个DatagramPacket实例)将需要发送的信息封装。

接受信息,创建一个数据报文(一个DatagramPacket实例),存储接受的报文信息。

构造方法:

用于接收的:

public DatagramPacket (byte[] buf,int length)  //接收长度为length的数据包

public DatagramPacket (byte[] buf, int offset, int length)//接收长度为length的数据包,在缓冲区中指定了偏移量

用于发送的:

public DatagramPacket (byte[] buf, int offset, int length,InetAddress address,int port):构造数据报包,将长度为length 偏移量为offset的包发送到指定主机上的指定端口号

public DatagramPacket (byte[] buf,  int length,InetAddress address,int port):构造数据报包,将长度为length 的包发送到指定主机上的指定端口号

public DatagramPacket (byte[] buf, int offset, int length, SocketAddress address)throws SocketException 构造数据报包,将长度为length  偏移量为offset的包发送到指定主机上的指定端口号

public DatagramPacket (byte[] buf, int length, SocketAddress address)throws SocketException 构造数据报包,将长度为length 的包发送到指定主机上的指定端口号

设置地址和端口的方法:

public void setAddress(InetAddress iaddr)  //设置目标主机IP地址

public void setPort(int iport)  //设置目标程序的端口

public void setSocketAddress(SocketAddress address) //设置数据包的目的地(包括IP地址和端口号)

提供对数据处理的方法:

public void setData(byte[] buf)//设置长度为buf 的数据缓冲区

public void setData(byte[] buf,int offset, int length)//设置包的数据为buf,长度为length  偏移量为offset的数据缓冲区


2.DatagramSocket类:(表示数据包套接字,进行端到端通信的类)

发送和接收UDP数据包= 接收和发送DatagramSocket对象

构造方法:

public  DatagramSocket() throws SocketException //发送方使用

public DatagramSocket(int port) throws SocketException //接收方使用,制定了监听的端口,只接受发往该端口的数据报。

public DatagramSocket(int port,InetAddress address) throws SocketException //接收方使用,制定了监听的地址和端口,只接受发往该地址和端口的数据报。

public DatagramSocket(SocketAddress bindaddr) throws SocketException //创建数据报套接字,指定了套接字地址,一般包含IP地址和端口

public DatagramSocket(DatagramSocketImpl impl)///创建带有指定DatagramSocketImpl数据报套接字

UDP发送和接受数据方法:

public  void send( DatagramPacket p) throws IOException  //发送封装好的数据报

public  void receive( DatagramPacket p) throws IOException  //接收数据报,调用此方法后,将用接受的数据填充指定数据报对象。

用于限制UDP数据报发送方和接收方的方法:

public void connect(InetAddress address,int port) //连接指定IP地址和端口的目的地址,建立连接后,接收方只接受目的地址发送的数据报

public void connect(SocketAddress addr) throws SocketException  //连接指定套接字地址,建立连接后,接收方只接受目的地址发送的数据报

discount()  用于断开连接

举个栗子:

客户端封装数据报,通过UDP套接字发送出去,服务端一直使用UDP套接字监听指定端口,当监听到数据报时,接收并填充数据报对象,并返回确认信息给客户端,客户端接收并填充数据报对象。

客户端:(DatagramSocket数据报套接字只用创建一个,可用于发送和接收数据报;DatagramPacket数据报要创建一个用于封装发送,一个用于填充接收到的服务端的确认信息的数据报)

socket通讯编程_第8张图片

客户端:(DatagramSocket数据报套接字只用创建一个,可用于发送和接收数据报;DatagramPacket数据报要创建一个用于接受数据,一个用于封装并发送确认信息的数据报)

socket通讯编程_第9张图片

四、HTTP编程:

http传输模式:c/s模型,由客户端发起请求,服务端回送响应。

过程:1.建立http连接,该连接基于TCP可靠传输之上

2.建立连接后,客户端向服务器发送http请求,(请求方式get、post等)

3.服务端接收请求后处理,将处理结果返回客户端

4.应答结束,关闭http连接(每次应答都要!!因为每次的请求之间无关)


举个栗子:编写简单的应用服务器,可为每个请求客户端建立连接,接受并解析客户端请求消息,处理用户请求,将处理结果封装成http响应消息发送给客户端。

server:

socket通讯编程_第10张图片

这里没有贴客户端的代码,需要http请求消息格式。



总结:

1

socket通讯编程_第11张图片
socket通讯编程_第12张图片

2、字符串转字节数组:

byte[] buf=mes.getBytes();

字节数组转字符串:

String backMes=new String(buf,0,getPacket.getLength());


3、从文件中读取输入流:

int read():读取一个字节,并返回读取的字节,无数据时返回-1

int read(byte[] b):读取多个字节,并存储到数组b中,无数据时返回-1

int read(byte[] b,int off,int len):从数组b的索引off开始读取len个字节

用file、inputstream

socket通讯编程_第13张图片

写入文件:PrintWriter和FileWriter

socket通讯编程_第14张图片

你可能感兴趣的:(socket通讯编程)