Java网络编程基础-- 基于TCP/IP的Socket编程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java网络编程基础-- 基于TCP/IP的Socket编程相关的知识,希望对你有一定的参考价值。
本节讲点:
客户端套接字:Socket:Socket的创建和使用方法,以及Socket选项和异常。
服务端套接字:ServerSocket:SeverSocket的创建和使用方法,以及ServerSocket选项
简单的Client/Server对话程序
支持多客户端的Client/Server服务响应程序
在学习JDK的网络编程之前先要了解一下网络基础知识和网络协议。
TCP(传输控制协议)一种基于连接的通信协议。可靠传输
UDP(用户数据包协议)不稳定连接的通信协议
TCP和UDP的端口如下:
Telnet:23
SMTP(简单邮件传输协议):25
HTTP(超文本传输协议):80
POP3:110
IP地址类InetAddress
Socket编程意在建立服务器端IP和客户端IP的网络通信连接,因此IP的寻址是建立连接的基础。InetAddress类是Java的IP地址封装类,表示互联网协议地址。IP地址是IP使用的32位或128位无符号数字,它是低级协议,TCP和UDP协议都是在它的基础上构建的。InetAddress类提供了如下操作:
创建InetAddress对象的方法。
InetAddress类没有构造方法,要创建该类的实例对象,可以通过该类的静态方法获得该对象。
(1)取得本机地址:getLocalHost()
函数定义:public static InetAddress getLocalHost() throws UnkonwnHostException; 示例: try{ //取得本机地址 InetAddress local = InetAddress.getLocalhost(); System.out.println(local); }catch(UnkownHostException e){}
(2)根据主机名获取地址:getByName(String host);
(3)根据主机名取得一组地址:getAllByName(String host);
(4)根据IP取得地址:getByAddress(byte[] addr);
IPv4地址中,使用4个字节表示,IPv6中使用6个字节表示
(5)根据主机名和IP取得地址:getByAddress(String host,byte[] addr)
2、取得InetAddress类的属性
获取此IP地址的完全限定域名
String getCanonicalHostName();
返回IP地址字符串
String getHostAddress();
获取此IP地址的主机名
String getHostName();
3、判断地址的版本是IPv4还是IPv6
try{ //取得本机地址 InetAddress local = InetAddress.getLocalHost(); //IPv4 or IPv6 byte[] addr = local.getAddress(); if(addr.length == 4){ System.out.println("IP版本 is IPv4"); int firstByte = addr[0]; if(firstByte < 0){ firstByte += 256; } if((firstByte & 0x80) == 0){ System.out.println("IP类别 is A"); }else if((firstByte & 0xC0) == 0){ System.out.println("IP类别 is B"); }else if((firstByte & 0xE0) == 0){ System.out.println("IP类别 is C"); }else if((firstByte & 0xF0) == 0){ System.out.println("IP类别 is D"); }else if((firstByte & 0xF8) == 0){ System.out.println("IP类别 is E"); } }else if(addr.length == 6){ System.out.pringln("IP 版本 is IPv6"); } }catch(UnkownHostExcetion e){ e.printStackTrace(); }
4、客户端套接字Socket
套接字(Socket)允许程序把网络连接当成一个流,可以向这个流写字节,也可以从这个流中读取字节。套接字为程序员屏蔽了网络的底层细节。
Socket是网络上运行的两个程序间双向通信的一段,它可以接受请求,也可以发送请求,利用它较为方便地编写网络上数据的传递。
Socket的工作过程如下:
(1)、连接到远程机器
(2)、绑定到端口
(3)、接收从远程机器来的绑定端口的连接
(4)、监听到达的数据
(5)、发送数据
(6)、接收数据
(7)、关闭连接
1、创建套接字对象
建立一个到主机host、端口号为port的套接字,连接到远程主机,方法如下:
public Socket(String host,int port) throws unkownHostException IOException; 示例如下: try{ Socket socket = new Socket("www.baidu.om",80); }catch(unkownHostException uex){ }catch(IOException e){ }
建立一个套接字,与前一个不同的是它用InetAddress对象指定套接字,如果出错则抛出IOException
public Socket(InetAddress host,int port) throws IOException; 示例如下: try{ InetAddress addr = InetAddress.getByName("www.baidu.com"); Socket socket = new Socket(addr,80); }catch...
5、服务器端套接字ServerSocket
每个服务器套接字运行在服务器上有特定的端口,监听这个端口的TCP连接。当远程客户端的Socket试图与服务器指定端口连接时,服务器被激活,判断客户端的连接,并打开两个主机之间固有的连接。一旦客户端与服务器建立了连接,则两者之间就可以传送数据,而数据时通过这个固有的套接字传递的。
ServerSocket的工作过程如下:
(1)、用ServerSocket()方法在指定端口创建一个新的ServerSocket对象
(2)、ServerSocket对象调用accept()方法在指定端口监听到来的连接。accept()一直处于阻塞状态,知道有客户端试图建立连接,这时accept()方法返回连接客户端与服务器的Socket对象
(3)、调用getInputStream()方法或者getOutputStream()方法,或者两者全调用,建立与客户端交互的输入流或输出流。
(4)、服务器与客户端根据一定的协议交互,知道关闭连接
(5)、服务器、客户端或者两者都关闭连接。
(6)、服务器回到第2步,继续监听下一个连接
1、创建SeverSocket对象
创建绑定到特定端口的服务器套接字
ServerSocket(int port);
try{ SeverSocket server = new ServerSocket(12345); }catch(IOException e){ }
利用指定的backlog创建服务器套接字,并将其绑定到指定的本地端口。backlog表示传入连接指示(对连接的请求)的最大队列长度,如果队列满时受到连接提示,则拒绝连接。backlog参数必须是大于0的正值,如果传递的值小于或者等于0,则使用默认值。
ServerSocket(int port,int backlog);
try{ SeverSocket server = new ServerSocket(12345,20); }catch(IOException e){ }
服务器端示例如下:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; /** * @author Administrator * Java socket 服务器端简单示例 */ public class OneServer { public static void main(String[] args) { // 启动服务器端 ServerSocket server = null; try { server = new ServerSocket(12345); System.out.println("服务器启动"+ server.getInetAddress().getHostAddress()+":"+ server.getLocalPort()); while(true){ //监听客户端 Socket socket = server.accept(); System.out.println("客户端连接"+ socket.getInetAddress().getHostAddress()+":"+ socket.getPort()); //输入输出流 BufferedReader sin = new BufferedReader(new InputStreamReader(System.in)); BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter os = new PrintWriter(socket.getOutputStream()); //循环处理客户端输入 String line; while((line = is.readLine()) != null){ System.out.println("收到客户端:"+line); if(line.equals("bye")){ System.out.println("拜拜,我上天去了"); break; }else{ //读取键盘输入并回复客户端 os.println(sin.readLine()); os.flush(); } } //关闭输入/输出流 is.close(); os.close(); //关闭客户端 socket.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { server.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
客户端示例:
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class OneClient { public static void main(String[] args) { // TODO Auto-generated method stub try { //连接服务器 Socket socket = new Socket(InetAddress.getLocalHost(),12345); //输入输出流 BufferedReader sin = new BufferedReader(new InputStreamReader(System.in)); BufferedReader is = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter os = new PrintWriter(socket.getOutputStream()); //循环读入键盘输入内容 String readLine; while((readLine = sin.readLine()) != null){ os.println(readLine); os.flush(); //读取服务器端回复 String responeLine = is.readLine(); System.out.println("服务器端回复:"+responeLine); } //关闭输出流 is.close(); os.close(); //关闭客户端 socket.close(); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
运行结果
本文出自 “阿酷博客源” 博客,请务必保留此出处http://aku28907.blog.51cto.com/5668513/1775429
以上是关于Java网络编程基础-- 基于TCP/IP的Socket编程的主要内容,如果未能解决你的问题,请参考以下文章
Java 网络编程--------------------基于TCP/IP(加入多线程)