您的位置:首页 > 理论基础 > 计算机网络

Java网络编程基础(二)-- 基于TCP/IP的Socket编程

2016-05-20 15:52 911 查看
本节讲点:
客户端套接字: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();
}
}

}
运行结果


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java Socket 网络编程