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

Java网络编程-(1)套接字

2016-10-07 14:34 288 查看

URL类:

url(Uniform Resource Locator),一个URL对象通常包含最基本的三部分信息:协议,地址,资源。协议如Http, Ftp, File。地址为有效的IP地址。资源是注意上的任何一个文件。
URL的构造方法: public URL(String spec) throws MalformedURLException和 public URL(String protocol, String host, String file)throws MalformedURLException.
读取URL中的资源:调用InputStream openStream()。
import java.net.*;
import java.io.*;
import java.util.*;
class Look implements Runnable{ /*URL资源的读取可能会引起阻塞,因此,程序需在一个线程中读取URL资源,以免阻塞主线程*/
URL url;
void setURL(String str){
try{
URL url = new URL(str);
this.url = url;
}
catch(MalformedURLException e){}
}
public void run(){
try{
InputStream in = url.openStream();
byte [] b = new byte[1024];
int n = -1;
while( (n=in.read(b))!=-1 ){
String str = new String(b, 0, n);
System.out.print(str);
}
}
catch(IOException exp){}
}
}
public class E{
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
Look look = new Look();
Thread readURL = new Thread(look);
System.out.println("输入URL资源,例如:http://www.baidu.com");
String source = scanner.nextLine();
look.setURL(source);
readURL.start();
}
}

InetAddress类:

1.获取internet上主机的地址:通过InetAddress类的静态方法getByName(String s)将一个域名或IP地址传递给该方法的参数s,获得一个InetAddress对象,该对象包含的信息为(例子):www.sina.com.cn/202.108.37.40
2.获取本机的地址:getLocalHost()。

套接字:

套接字概述:网络通信使用IP地址标识Internet上的计算机,使用端口号标识服务器上的进程(程序)。当连个程序需要通信时,它们可以通过使用Socket类建立套接字对象并连接在一起(端口号与IP地址组合得出一个网络套接字)。

客户端套接字:客户端程序使用Socket类建立负责连接到服务器的套接字对象,即客户负责呼叫。Socket的构造方法Socket(String host, int port) throws IOException.套接字对象clientSocket建立后,clientSocket可以使用getInputStream()获得一个输入流,这个输入流的源和服务器端的一个输出流的目的地刚好相同,因此客户端用输入流可以读取服务器写入到输出流中的数据。同理,getOutputStream()
,服务器用输入流可以读取客户写入到输出流的数据。

try{
Socket clientSocket = new Socket("http://192.168.0.78", 2010);
}
catch(IOException e){}


ServerSocket对象与服务器端套接字:为了能使客户成功地连接到服务器,服务器必须建立一个ServerSocket对象,该对象通过将客户端的套接字对象和服务器端的一个套接字对象连接起来,从而达到连接的目的。ServerSocket的构造方法为ServerSocket(int port) throws IOException.当建立了ServerSocket的对象后,就可以使用方法accept()将客户端的套接字和服务器的套接字连接起来。示例代码如下:

try{
ServerSocket serverForClient = new ServerSocket(2010);
Socket sc = serverForClient.accept();
}
catch(IOException e){}
accept()方法返回一个和客户端Socket对象相连接的Socket对象sc,sc驻留在服务器端。sc调用getOutputStream()获得的输出流将指向客户端的输入流。同样,调用getInputStream()获得的输入流将指向客户端的输出流。如下图:



注意:从文件中读取数据时,所有的数据都已经在文件中了。而使用套接字连接时,可能在另一端数据发送之前,就已经开始读取了,这时,就会阻塞本线程

,直到该读取方法成功读取到信息,本线程才继续执行后续的操作。accept()方法也会阻塞线程的执行,直到接收到客户的呼叫。

建立连接后,服务器端的套接字对象调用getInetAddress()方法获取客户端的IP地址和域名。客户端的套接字对象调用getInetAddress()方法获取服务器的IP地址和域名。通信完毕后,套接字应使用close()方法关闭套接字连接。示例如下:

import java.net.*;
import java.io.*;
public class Server{
public static void main(String args[]){
String [] answer = {"Hi", "Caka", "Fine!"};
a642
ServerSocket serverForClient = null;//服务器套接字对象,负责本程序的端口
Socket socketOnServer = null; //accept()之后返回的连接好的对象
DataOutputStream out = null;
DataInputStream in = null;
try{
serverForClient = new ServerSocket(2010);
}
catch(IOException e){
System.out.println(e);
}
try{
System.out.println("等待客户呼叫");
socketOnServer = serverForClient.accept();//阻塞状态,除非有客户呼叫
out = new DataOutputStream(socketOnServer.getOutputStream());
in = new DataInputStream(socketOnServer.getInputStream());
for(int i=0; i<answer.length; i++){
String msg = in.readUTF();  //in读取信息,阻塞状态
System.out.println("服务器收到客户的提问"+msg);
out.writeUTF(answer[i]);
Thread.sleep(500);
}
}
catch(Exception e){
System.out.println("客户已断开"+e);
}
}
}
import java.net.*;
import java.io.*;
public class Client{
public static void main(String args[]){
String [] msg = {"hello", "What is your name?", "How are you?"};
Socket clientSocket; //客户端套接字对象
DataInputStream in = null;
DataOutputStream out = null;
try{
//客户端套接字对象,负责绑定IP地址和端口
clientSocket = new Socket("172.20.17.235", 2010);
in = new DataInputStream(clientSocket.getInputStream());
out = new DataOutputStream(clientSocket.getOutputStream());
for(int i=0; i<msg.length; i++){
out.writeUTF(msg[i]);  //out发送信息
String str = in.readUTF(); //in接收信息,阻塞状态
System.out.println("客户收到服务器的回答:"+str);
Thread.sleep(500);
}
}
catch(Exception e){
System.out.println("服务器已断开"+e);
}
}
}


使用多线程技术:即在可能发生阻塞的地方使用线程

在套接字通信中,有两个基本原则:
1.服务器应当启动一个专门的线程,在该线程中和客户的套接字建立连接。
2.由于套接字的输入流在读取信息时可能发生阻塞,客户端和服务器端都需要在一个单独的线程中读取信息。
服务器端:
import java.net.*;
import java.io.*;
import java.util.*;
class ServerThread extends Thread{
Socket socketOnServer = null;
DataOutputStream out =null;
DataInputStream in = null;
Scanner scanner = new Scanner(System.in);
ServerThread(Socket socketOnServer){
this.socketOnServer = socketOnServer;
try{
out = new DataOutputStream(socketOnServer.getOutputStream());
in = new DataInputStream(socketOnServer.getInputStream());
//构造读线程
Read read = new Read();
read.setDataInputStream(in);
Thread readThread = new Thread(read);
readThread.start();
}
catch(IOException e){}
}
public void run(){
//服务器线程的run函数,负责写
System.out.print("Server: ");
while(scanner.hasNext()){
try{
String outMsg = null;
System.out.print("Server: ");
outMsg = scanner.nextLine();
out.writeUTF(outMsg);
}
catch(IOException e){
System.out.println("客户离开");
return;
}
}
}
}
class Read implements Runnable{
DataInputStream in;
public void setDataInputStream(DataInputStream in){
this.in = in;
}
public void run(){
//读线程,负责读
while(true){
try{
String inMsg = in.readUTF();
System.out.println("Client: "+inMsg);
}
catch(IOException e){
System.out.println("与客户端已断开");
break;
}
}
}
}
public class Server{
public static void main(String args[]){
//服务器套接字,负责本服务器的端口
ServerSocket serverForClient = null;
//accept()后返回的套接字,驻留在Server上
Socket socketOnServer = null;
while(true){
try{
//绑定端口
serverForClient = new ServerSocket(2016);
}
catch(IOException e){
System.out.println("正在监听");
}
try{
System.out.println("等待客户呼叫");
//套接字连接
socketOnServer = serverForClient.accept();
//输出客户端的IP地址
System.out.println("客户的地址:"+socketOnServer.getInetAddress());
}
catch(IOException e){
System.out.println("正在等待客户");
}
if(socketOnServer!=null){
//为每个客户启动一个专门的线程
new ServerThread(socketOnServer).start();
}
}
}
}
客户端:
import java.net.*;
import java.io.*;
import java.util.*;
class Read implements Runnable{
DataInputStream in;
public void setDataInputStream(DataInputStream in){
this.in = in;
}
public void run(){
while(true){
try{
String msg = in.readUTF();
System.out.println("Server: "+msg);
}
catch(IOException e){
System.out.println("客户端退出");
break;
}
}
}
}
public class Client{
public static void main(String args[]){
Scanner scanner = new Scanner(System.in);
//客户端套接字
Socket clientSocket = null;
DataOutputStream out = null;
DataInputStream in = null;
//读线程
Thread readThread = null;
//Read接口
Read read = null;
try{
//使用connect函数绑定服务器
clientSocket = new Socket();
read = new Read();
readThread = new Thread(read);
//获取本机IP地址
InetAddress localHost = InetAddress.getLocalHost();
//构造InetSocketAddress类对象
InetSocketAddress socketAddress = new InetSocketAddress(localHost, 2016);
clientSocket.connect(socketAddress);
out = new DataOutputStream(clientSocket.getOutputStream());
in = new DataInputStream(clientSocket.getInputStream());
read.setDataInputStream(in);
//读线程开启
readThread.start();
}
catch(Exception e){
System.out.println("服务器已断开"+e);
}
System.out.println("Client: ");
while(scanner.hasNext()){
try{
System.out.println("Client: ");
out.writeUTF(scanner.nextLine());
}
catch(Exception e){

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