黑马程序员 java语言网络编程概述

                         ------- android培训java培训、期待与您交流! ----------

计算机网络

    是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起 来, 的计算机系统。

网络编程

    就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。

 

网络模型

OSIOpen System Interconnection开放系统互连)参考模型

TCP/IP参考模型

 

网络通信三要素

IP地址:InetAddress

网络中设备的标识,不易记忆,可用主机名

端口号

用于标识进程的逻辑地址,不同进程的标识

传输协议

通讯的规则

常见协议:TCPUDP

 

IP地址

要想让网络中的计算机能够互相通信,必须为每台计算机指定一个标识号,通过这个标识号来指定要接受数据的计算机和识别发送的计算机,在TCP/IP协议中,这个标识号就是IP地址。

那么,我们如果获取和操作IP地址呢?

获取任意主机:getByName

主机名:getHostName

主机Ip地址:getHostAddress

 

为了方便我们对IP地址的获取和操作,java提供了一个类InetAddress 供我们使用。

如下:

import java.net.InetAddress;

import java.net.UnknownHostException;

 * InetAddress的成员方法:

 * public static InetAddress getByName(String host):根据主机名或者IP地址的字符串表示得到IP地址对象

 */

public class InetAddressDemo {

public static void main(String[] args) throws UnknownHostException {

// public static InetAddress getByName(String host)

// InetAddress address = InetAddress.getByName("liupanmin");//根据主机名获得ip地址对象

// InetAddress address = InetAddress.getByName("192.168.12.92");//根据IP地址字符                   串表示得到IP地址对象

InetAddress address = InetAddress.getByName("192.168.12.63");

 

// 获取:主机名,IP地址

// public String getHostName()

String name = address.getHostName();//获取主机名

// public String getHostAddress()

String ip = address.getHostAddress();//获取IP地址

System.out.println(name + "---" + ip);

}

}

 

端口号:

        a、用于标识进程的逻辑地址,不用进程的标识。

        b、有效端口:0 ~65535,系统使用或保留的端口是:0~ 1024。

传输协议:

        即通信规则,包含TCP和UDP协议

 

UDP

        是面向无连接,明确了对方的端口,无论在不在网上,只管传输,不在就会丢失数据。只求速度,应用于网络视频会议和聊天等应用程序中。

协议特点:

         a、面向无连接,即将数据及源和目的封装成数据包中,不建立链接的发送

         b、每个数据包的大小限制在64K之内

         c、因无连接,是不可靠的协议

         d、不建立连接,速度快。

TCP

        是面向连接的,必须连接成功才能传输数据,应用于下载等程序上

协议特点:

         a、面向连接,在建立连接后,形成传输数据的通道

         b、在连接中进行大数据量的传输

         c、通过三次握手完成连接,是可靠的协议

         d、必须建立连接,效率稍慢

三次握手:第一次本方发送请求,第二次对方确认连接,第三次本方再次确认连接成功。

   通信的步骤:

        1)找到IP地址

        2)数据要发送到对象指定应用程序,为标识这些应用程序,所以给这些网络应用程序都用数字标识,为方便称呼这个数字,叫做端口,即逻辑端口。

        3)定义通信规则,称之为协议。国际组织定义了通用协议,即TCP/IP。

注意:必须要有数字标识才能将数据发送到应用程序上

UDP传输

1、通过类DatagramSocket,此类表示用发送和接收数据包的套接字,即Socket。

2、方法:

        1)创建 UDPSocket发送服务对象:

              DatagramSocket(),不指定端口。DatagramSocket(int port),指定端口。

        2)发送:void send(DatagramPacket p)

        3)接收:void receive(DatagramPacket p)

       其中DatagramPacket:数据报包用来实现无连接包投递服务的,每条报文仅根据该包中包含的信息从一台机器路由到另一台机器中。凡是带地址(InetAddress)的都是用于发送包的

 

DP传输-发送端思路

1:建立udpsocket服务

2:将要发送的数据封装成数据包

3:通过udpsocket服务,将数据包发送出

4:关闭资源

 

UDP传输-接收端思路

1:建立udpsocket服务.

2:通过receive方法接收数据

3:将收到的数据存储到数据包对象中

4:通过数据包对象的功能来完成对接收到数据进行解析.

5:可以对资源进行关闭

 

 

下面看一个小事例

UDP 接受数据

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

 

/*

 * UDP协议接收数据:

 * A:创建接收端Socket对象

 * B:创建一个数据包(接收容器)

 * C:调用Socket对象的接收方法接收数据

 * D:解析数据包,并显示在控制台

 * E:释放资源

 */

public class ReceiveDemo {

public static void main(String[] args) throws IOException {

// 创建接收端Socket对象

// DatagramSocket(int port)

DatagramSocket ds = new DatagramSocket(10086);

 

// 创建一个数据包(接收容器)

// DatagramPacket(byte[] buf, int length)

byte[] bys = new byte[1024];

int length = bys.length;

DatagramPacket dp = new DatagramPacket(bys, length);

 

// 调用Socket对象的接收方法接收数据

// public void receive(DatagramPacket p)

ds.receive(dp); // 阻塞式

 

// 解析数据包,并显示在控制台

// 获取对方的ip

// public InetAddress getAddress()

InetAddress address = dp.getAddress();

String ip = address.getHostAddress();

// public byte[] getData():获取数据缓冲区

// public int getLength():获取数据的实际长度

byte[] bys2 = dp.getData();

int len = dp.getLength();

String s = new String(bys2, 0, len);

System.out.println(ip + "传递的数据是:" + s);

 

// 释放资源

ds.close();

}

}

UDP发送数据:

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

/*

 * UDP协议发送数据:

 * A:创建发送端Socket对象

 * B:创建数据,并把数据打包

 * C:调用Socket对象的发送方法发送数据包

 * D:释放资源

 */

public class SendDemo {

public static void main(String[] args) throws IOException {

// 创建发送端Socket对象

// DatagramSocket()

DatagramSocket ds = new DatagramSocket();

 

// 创建数据,并把数据打包

// DatagramPacket(byte[] buf, int length, InetAddress address, int port)

// 创建数据

byte[] bys = "hello,udp,我来了".getBytes();

// 长度

int length = bys.length;

// IP地址对象

InetAddress address = InetAddress.getByName("192.168.12.92");

// 端口

int port = 10086;

DatagramPacket dp = new DatagramPacket(bys, length, address, port);

 

// 调用Socket对象的发送方法发送数据包

// public void send(DatagramPacket p)

ds.send(dp);

 

// 释放资源

ds.close();

}

}

 

具体事例代码二:

import java.io.IOException;

import java.net.DatagramSocket;

 

/*

 * 通过多线程改进刚才的聊天程序,这样我就可以实现在一个窗口发送和接收数据了

 */

public class ChatRoom {

public static void main(String[] args) throws IOException {

DatagramSocket dsSend = new DatagramSocket();

DatagramSocket dsReceive = new DatagramSocket(12306);

 

SendThread st = new SendThread(dsSend);

ReceiveThread rt = new ReceiveThread(dsReceive);

 

Thread t1 = new Thread(st);

Thread t2 = new Thread(rt);

 

t1.start();

t2.start();

}

}

import java.io.IOException;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

 

public class ReceiveThread implements Runnable {

private DatagramSocket ds;

 

public ReceiveThread(DatagramSocket ds) {

this.ds = ds;

}

 

@Override

public void run() {

try {

while (true) {

// 创建一个包裹

byte[] bys = new byte[1024];

DatagramPacket dp = new DatagramPacket(bys, bys.length);

 

// 接收数据

ds.receive(dp);

 

// 解析数据

String ip = dp.getAddress().getHostAddress();

String s = new String(dp.getData(), 0, dp.getLength());

System.out.println("from " + ip + " data is : " + s);

}

} catch (IOException e) {

e.printStackTrace();

}

}

 

}

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

 

public class SendThread implements Runnable {

 

private DatagramSocket ds;

 

public SendThread(DatagramSocket ds) {

this.ds = ds;

}

 

@Override

public void run() {

try {

// 封装键盘录入数据

BufferedReader br = new BufferedReader(new InputStreamReader(

System.in));

String line = null;

while ((line = br.readLine()) != null) {

if ("886".equals(line)) {

break;

}

 

// 创建数据并打包

byte[] bys = line.getBytes();

// DatagramPacket dp = new DatagramPacket(bys, bys.length,

// InetAddress.getByName("192.168.12.92"), 12345);

DatagramPacket dp = new DatagramPacket(bys, bys.length,

InetAddress.getByName("192.168.12.255"), 12306);

 

// 发送数据

ds.send(dp);

}

 

// 释放资源

ds.close();

} catch (IOException e) {

e.printStackTrace();

}

}

 

 

TCP传输

SocketServerSocket

建立客户端和服务器端

建立连接后,通过Socket中的IO流进行数据的传输

关闭socket

同样,客户端与服务器端是两个独立的应用程序。

TCP传输

1、TCP分客户端和服务端。客户端对应的对象是Socket,服务端对应的对象是ServerSocket。

2、方法:

        1)创建客户端对象:

              Socket():创建空参数的客户端对象,一般用于服务端接收数据

              Socket(String host,int port),指定要接收的IP地址和端口号

        2)创建服务端对象:ServerSocket(int port):指定接收的客户端的端口

        3)Socket accept():监听并接受到此套接字的连接

        4)void shutdownInput():此套接字的输入流至于流的末尾

        5)void shutdownOutput():禁用此套接字的输出流

        6)InputStream getInputStream():返回此套接字的输入流,Socket对象调用

        7)OutputStream getOutputStream():返回套接字的输出流,Socket对象调用

3、基本思路

客户端:

        1)客户端需要明确服务器的ip地址以及端口,这样才可以去试着建立连接,如果连接失败,会出现异常。

        2)连接成功,说明客户端与服务端建立了通道,那么通过IO流就可以进行数据的传输,而Socket对象已经提供了输入流和输出流对象,通过getInputStream(),getOutputStream()获取即可。

        3)与服务端通讯结束后,关闭Socket。

服务端:

        1)服务端需要明确它要处理的数据是从哪个端口进入的。

        2)当有客户端访问时,要明确是哪个客户端,可通过accept()获取已连接的客户端对象,并通过该对象与客户端通过IO流进行数据传输。

        3)当该客户端访问结束,关闭该客户端。

4、步骤

客户端:

        通过查阅Socket对象的API文档,发现在该对象在建立时,就可去连接指定主机,因为TCP是面向连接的,所以在建立Socket服务时,就要有服务端存在,并连接成功,形成通路后,再通过该通道进行数据的传输。

         1)创建Socket服务,并指定要连接的主机端口。通路一建立,就会产生Socket流(包括输入流和输出流),通过方法获取

         2)为了发送数据,应获取Socket中的输出流,如果要接收服务端的反馈信息,还需要获取Socket的输入流

         3)通过输出流的write()方法将要发送的数据写入到流中

         4)关闭Socket流资源

服务端:

        服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。需监听一个端口。

         1)建立服务端的Socket服务,并监听一个端口。通过ServerSocet带端口参数的构造函数

         2)获取连接过来的客户对象,通过ServerSocket的accept()方法,此方法是阻塞式的,如果服务端没有连接到就会一直等待

         3)客户端如果发过来数据,则服务端要使用对应的客户端对象,并获取到该客户端对象的读取流读取发过来的数据,并输出到指定目的地。

         4)关闭服务端(可选)。一般服务端是常开的,因为在实际应用中,随时有客户端在请求连接和服务。但这里需要定时关闭客户端对象流,避免某一个客户端长时间占用服务器端。

 

TCP传输-客户端思路

1:建立客户端的Socket服务,并明确要连接的服务器。

2:如果连接建立成功,就表明,已经建立了数据传输的通道.就可以在该通道通过IO进行数据的读取和写入.该通道称为Socket,Socket流中既有读取流,也有写入流.

3:通过Socket对象的方法,可以获取这两个流

4:通过流的对象可以对数据进行传输

5:如果传输数据完毕,关闭资源

TCP传输-服务器端思路

1:建立服务器端的socket服务,需要一个端口

2:服务端没有直接流的操作,而是通过accept方法获取客户端对象,在通过获取到的客户端对象的流和客户端进行通信

3:通过客户端的获取流对象的方法,读取数据或者写入数据

4:如果服务完成,需要关闭客户端,然后关闭服务器,但是,一般会关闭客户端,不会关闭服务器,因为服务端是一直提供服务的

 

具体事例代码一:

import java.io.IOException;

import java.io.OutputStream;

import java.net.Socket;

 

/*

 * TCP协议发送数据:

 * A:创建发送端的Socket对象

 *  这一步如果成功,就说明连接已经建立成功了。

 * B:获取输出流,写数据

 * C:释放资源

 * 

 * 连接被拒绝。TCP协议一定要先看服务器。

 * java.net.ConnectException: Connection refused: connect

 */

public class ClientDemo {

public static void main(String[] args) throws IOException {

// 创建发送端的Socket对象

// Socket(InetAddress address, int port)

// Socket(String host, int port)

// Socket s = new Socket(InetAddress.getByName("192.168.12.92"), 8888);

Socket s = new Socket("192.168.12.92", 8888);

 

// 获取输出流,写数据

// public OutputStream getOutputStream()

OutputStream os = s.getOutputStream();

os.write("hello,tcp,我来了".getBytes());

 

// 释放资源

s.close();

}

}

import java.io.IOException;

import java.io.InputStream;

import java.net.ServerSocket;

import java.net.Socket;

 

/*

 * TCP协议接收数据:

 * A:创建接收端的Socket对象

 * B:监听客户端连接。返回一个对应的Socket对象

 * C:获取输入流,读取数据显示在控制台

 * D:释放资源

 */

public class ServerDemo {

public static void main(String[] args) throws IOException {

// 创建接收端的Socket对象

// ServerSocket(int port)

ServerSocket ss = new ServerSocket(8888);

 

// 监听客户端连接。返回一个对应的Socket对象

// public Socket accept()

Socket s = ss.accept(); // 侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。

 

// 获取输入流,读取数据显示在控制台

InputStream is = s.getInputStream();

 

byte[] bys = new byte[1024];

int len = is.read(bys); // 阻塞式方法

String str = new String(bys, 0, len);

 

String ip = s.getInetAddress().getHostAddress();

 

System.out.println(ip + "---" + str);

 

// 释放资源

s.close();

// ss.close(); //这个不应该关闭

}

}

 

事例代码二:

客户端键盘录入,服务器输出到控制台

客户端:public class ClientDemo {

public static void main(String[] args) throws IOException {

// 创建客户端Socket对象

Socket s = new Socket("192.168.12.92", 22222);

 

// 键盘录入数据

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

// 把通道内的流给包装一下

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(

s.getOutputStream()));

 

String line = null;

while ((line = br.readLine()) != null) {

// 键盘录入数据要自定义结束标记

if ("886".equals(line)) {

break;

}

bw.write(line);

bw.newLine();

bw.flush();

}

 

// 释放资源

// bw.close();

// br.close();

s.close();

}

服务端:

public class ServerDemo {

public static void main(String[] args) throws IOException {

// 创建服务器Socket对象

ServerSocket ss = new ServerSocket(22222);

 

// 监听客户端连接

Socket s = ss.accept();

 

// 包装通道内容的流

BufferedReader br = new BufferedReader(new InputStreamReader(

s.getInputStream()));

String line = null;

while ((line = br.readLine()) != null) {

System.out.println(line);

}

 

// br.close();

s.close();

// ss.close();

}

事例代码三:

客户端文本文件,服务器输出到控制台

public class ClientDemo {

public static void main(String[] args) throws IOException {

// 创建Socket对象

Socket s = new Socket("192.168.12.92", 34567);

 

// 封装文本文件

BufferedReader br = new BufferedReader(new FileReader(

"InetAddressDemo.java"));

// 封装通道内的流

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(

s.getOutputStream()));

 

String line = null;

while ((line = br.readLine()) != null) {

bw.write(line);

bw.newLine();

bw.flush();

}

 

br.close();

s.close();

}

}

服务端:

public class ServerDemo {

public static void main(String[] args) throws IOException {

// 创建服务器Socket对象

ServerSocket ss = new ServerSocket(34567);

 

// 监听客户端连接

Socket s = ss.accept();

 

// 封装通道内的流

BufferedReader br = new BufferedReader(new InputStreamReader(

s.getInputStream()));

 

String line = null;

while ((line = br.readLine()) != null) {

System.out.println(line);

}

 

s.close();

}

}

事例四:

文件上传

客户端

 

/*

 * 按照我们正常的思路加入反馈信息,结果却没反应。为什么呢?

 * 读取文本文件是可以以null作为结束信息的,但是呢,通道内是不能这样结束信息的。

 * 所以,服务器根本就不知道你结束了。而你还想服务器给你反馈。所以,就相互等待了。

 * 

 * 如何解决呢?

 * A:在多写一条数据,告诉服务器,读取到这条数据说明我就结束,你也结束吧。

 *  这样做可以解决问题,但是不好。

 * B:Socket对象提供了一种解决方案

 *  public void shutdownOutput()

 */

 

public class UploadClient {

public static void main(String[] args) throws IOException {

// 创建客户端Socket对象

Socket s = new Socket("192.168.12.92", 11111);

 

// 封装文本文件

BufferedReader br = new BufferedReader(new FileReader(

"InetAddressDemo.java"));

// 封装通道内流

BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(

s.getOutputStream()));

 

String line = null;

while ((line = br.readLine()) != null) { // 阻塞

bw.write(line);

bw.newLine();

bw.flush();

}

//自定义一个结束标记

// bw.write("over");

// bw.newLine();

// bw.flush();

//Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了

s.shutdownOutput();

 

// 接收反馈

BufferedReader brClient = new BufferedReader(new InputStreamReader(

s.getInputStream()));

String client = brClient.readLine(); // 阻塞

System.out.println(client);

 

 

 

服务器端:

public class UploadServer {

public static void main(String[] args) throws IOException {

// 创建服务器端的Socket对象

ServerSocket ss = new ServerSocket(11111);

 

// 监听客户端连接

Socket s = ss.accept();// 阻塞

 

// 封装通道内的流

BufferedReader br = new BufferedReader(new InputStreamReader(

s.getInputStream()));

// 封装文本文件

BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));

 

String line = null;

while ((line = br.readLine()) != null) { // 阻塞

// if("over".equals(line)){

// break;

// }

 

、用TCP客户端并发上传图片

1、一对一(单线程)上传的思路:

客户端

        a、服务端点。

        b、读取客户端已有的图片数据

        c、通过Socket输出流将数据发给服务端

        d、读取服务端反馈信息。

        e、关闭

服务端

        a、服务端服务,并监听窗口

        b、获取客户端对象,并获取客户ip

        c、读取客户端输入流数据

        d、写入文件

        e、用客户端输出流反馈信息

        f、关流

2、单线程的服务端有个局限性。当A客户端连接上以后,被服务端获取到。服务端执行具体流程。这时B客户端连接,只能等待。因为服务端还没有处理完A客户端的请求。还没有循环回来执行下一次accept方法。所以,暂时获取不到B客户端对象。

        那么为了可以让多个客户端同时并发访问服务端。服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。

如何定义线程呢?

        只要明确了每一个客户端要在服务端执行的代码,将该代码存入run方法即可。

代码:

[java] view plaincopy

/* 

需求:并发上传图片 

*/  

  

import java.io.*;  

import java.net.*;  

//客户端  

class  PicClient  

{  

    public static void main(String[] args) throws Exception  

    {  

        //对传入的值进行判断  

        if (args.length!=1)  

        {  

            System.out.println("请指定一个图片文件!");  

            return;  

        }  

  

        File file=new File(args[0]);  

  

        //对文件路径进行判断  

        if (!(file.exists()&&file.isFile()))  

        {  

            System.out.println("你上传的文件有问题,非文件或者不存在!");  

            return;  

        }  

  

        //判断是否是图片文件  

        if (!file.getName().endsWith(".jpg"))  

        {  

            System.out.println("图片格式错误,请重新选择!");  

            return;  

        }  

  

        //对文件大小进行判断  

        if (file.length()>1024*1024*5)  

        {  

            System.out.println("你上传的文件过大,居心叵测!");  

            return;  

        }  

  

        //创建服务  

        Socket s=new Socket("localhost",10000);  

        //读取图片数据  

        FileInputStream fis=new FileInputStream(file);  

          

        //Socket服务输出流写入数据  

        OutputStream out =s.getOutputStream();  

  

        BufferedReader in=new BufferedReader(new InputStreamReader(s.getInputStream()));  

  

        byte[] buf=new byte[1024];  

  

        int len=0;  

  

        while ((len=fis.read(buf))!=-1)  

        {  

            out.write(buf,0,len);  

        }  

  

        //结束标记,表示文件数据已经上传完了  

        s.shutdownOutput();  

  

        String info=in.readLine();//读取返回信息  

        System.out.println(info);  

  

        fis.close();//关流  

        s.close();  

  

    }  

}  

  

//服务端  

class PicServer  

{  

    public static void main(String[] args)throws Exception  

    {  

        //创建服务,监听端口  

        ServerSocket ss=new ServerSocket(10000);  

          

        while (true)  

        {  

            //获取客户端对象  

            Socket s=ss.accept();  

            //客户端执行线程  

            new Thread(new PicThread(s)).start();  

        }  

          

        //ss.close();  

    }  

}  

  

//利用多线程实现并发上传  

class PicThread implements Runnable  

{  

    private Socket s;  

    PicThread(Socket s)  

    {  

        this.s=s;  

    }  

    public void run()  

    {  

        int count=1;  

        //获取客户端ip  

        String ip=s.getInetAddress().getHostAddress();  

        try  

        {         

            System.out.println(ip+"  connected.....");  

  

            //通过客户端的读取流读取数据  

            InputStream in=s.getInputStream();  

            //文件保存路径  

            File dir =new File("C:\\Users\\asus\\Desktop");  

            //文件名  

            File file=new File(dir,ip+".jpg");  

            //判断文件是否存在  

            while(file.exists())  

            {  

                file=new File(dir,ip+"("+(count++)+").jpg");  

            }  

  

            //将数据写入到指定文件中  

            FileOutputStream fos=new FileOutputStream(file);  

  

            byte[] buf=new byte[1024];  

            int len=0;  

            while ((len=in.read(buf))!=-1)  

            {  

                fos.write(buf,0,len);  

            }  

  

            //将收到图片数据的信息返回给客户端  

            OutputStream out=s.getOutputStream();  

              

            out.write("上传成功!".getBytes());  

  

            fos.close();//关流  

            s.close();  

        }  

        catch (Exception e)  

        {  

            throw new RuntimeException(ip+"图片上传失败");  

        }  

    }  

}  

实现多人上传的功能,用到线程

客户端

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.net.Socket;

 

public class UploadPic implements Runnable {

 

private Socket s;

 

public UploadPic(Socket s) {

this.s = s;

}

 

@Override

public void run() {

 

try {

String ip = s.getInetAddress().getHostAddress();

System.out.println(ip + ".....connected");

 

// 读取图片数据。

InputStream in = s.getInputStream();

 

// 写图片数据到文件。

File dir = new File("e:\\uploadpic");

if (!dir.exists()) {

dir.mkdir();

}

// 为了避免覆盖,通过给重名的文件进行编号。

int count = 1;

File picFile = new File(dir, ip + "(" + count + ").jpg");

while (picFile.exists()) {

count++;

picFile = new File(dir, ip + "(" + count + ").jpg");

}

FileOutputStream fos = new FileOutputStream(picFile);

 

byte[] buf = new byte[1024];

int len = 0;

while ((len = in.read(buf)) != -1) {

fos.write(buf, 0, len);

}

 

// 给客户端一个回馈信息。

OutputStream out = s.getOutputStream();

out.write("上传成功".getBytes());

 

// 关闭资源。

fos.close();

s.close();

} catch (IOException e) {

 

}

 

}

 

}

 

服务器端:

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

 

public class UploadPicServer {

 

/**

 * @param args

 * @throws IOException

 */

public static void main(String[] args) throws IOException {

System.out.println("上传图片服务端运行......");

// 创建server  socket 

ServerSocket ss = new ServerSocket(10007);

 

while (true) {

// 获取客户端。

Socket s = ss.accept();

//实现多个客户端并发上传,服务器端必须启动做个线程来完成。

new Thread(new UploadPic(s)).start();

}

}

 

}

URL和URLConnection

1、URL:

        URI:范围更大,条形码也包含于此范围

        URL:范围较小,即域名

方法:

        1)构造函数:URL(String protocol,String host,int port,String file);//根据指定 protocol、host、port号和 file 创建 URL对象。

        2)String getProtocol();//获取协议名称

        3)String getHost();//获取主机名

        4)int getPort();//获取端口号

        5)String getFile();//获取URL文件名

        6)String getPath();//获取此URL的路径部分

        7)String getQuery();//获取此URL的查询部,客户端传输的特定信息

注:一般输入网址,是不带端口号的,此时可进行获取,通过获取网址返回的port,若port为-1,则分配一个默认的80端口,如

        int port = getPort();

        if(port == -1)

              port = 80;

2、URLConnection

方法:

        1)URLConnection openConnection();//用URL调用此方法,返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。

        2)InputStream getInputStream();//获取输入流

        3)OutputStream getOutputStream();//获取输出流

 

                                           ------- android培训java培训、期待与您交流! ----------

你可能感兴趣的:(黑马程序员 java语言网络编程概述)