黑马程序员--------------网络编程

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

 网络间的通信方式分为两种,一种是面向无连接(UDP),一种是面向连接(TCP)。而网络间的通信底层都遵循一种通信机制,也叫Socket,我把它理解为是一种端口,因为每个应用程序运行都有指定的端口进行数据的传输。所以在用前面的两种通信方式时都要指定相同的端口。UDP的特点:将数据及源和目的封装到数据包中,不需要建立连接;每个数据包的大小限制在64K内,如果数据包大于64K就会自动的将其分割成小的包;因为是无连接,所以是不可靠协议,但是传输速度相对较快。TCP的特点:需建立连接,形成传输数据的通道,并通过三次握手来确定通道的安全,因此传输效率稍低。

UDP传输的操作步骤:

发送端:

1,建立udp的socket服务,创建对象时如果没有明确端口,系统会自动分配一个未被使用的端口。

2,明确要发送的具体数据。

3,将数据封装成了数据包。

4,用socket服务的send方法将数据包发送出去。

5,关闭资源。

class  UdpSend{

    public static voidmain(String[] args)throws Exception {

    1,建立udp的socket服务。

        DatagramSocket ds = newDatagramSocket();//指定发送端口,不指定系统会随机分配。

  2,明确要发送的具体数据。

       //因为底层传输的是字节流,所以要把传送的内容变成字节数组再进行传输。

        byte[] buf = "UDP wo lai le".getBytes();

   3,将数据封装成了数据包。

       //创建一个数据包对象,DatagramPacket(byte[] buf, int length, InetAddress address, int port) 

      //buf - 包数据。length - 包长度,address - 目的地址。port - 目的端口号。

     

    DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),10000);

    4,用socket服务的send方法将数据包发送出去。

        ds.send(dp);

//      5,关闭资源。

        ds.close();

    }

}

udp的接收端

1,创建udp的socket服务,必须要明确一个端口,作用在于,只有发送到这个端口的数据才是这个接收端可以处理的数据。

2,定义数据包,用于存储接收到数据。

3,通过socket服务的接收方法将收到的数据存储到数据包中。

4,通过数据包的方法获取数据包中的具体数据内容,比如ip、端口、数据等等。

5,关闭资源。

lass UdpRece {

    public static voidmain(String[] args) throws Exception{

  1,创建udp的socket服务。

        DatagramSocket ds = newDatagramSocket(10000);

     2,定义数据包,用于存储接收到数据。先定义字节数组,数据包会把数据存储到字节数组中。

        byte[] buf = new byte[1024];

        DatagramPacket dp = newDatagramPacket(buf,buf.length);

     3,通过socket服务的接收方法将收到的数据存储到数据包中。

        ds.receive(dp);//该方法是阻塞式方法。

     4,通过数据包的方法获取数据包中的具体数据内容,比如ip,端口,数据等等。

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

        int port = dp.getPort();

        String text = newString(dp.getData(),0,dp.getLength());//将字节数组中的有效部分转成字符串。

        System.out.println(ip+":"+port+"--"+text);

    5,关闭资源。

        ds.close();

    }

}


TCP传输的操作步骤:

客户端:

1,建立tcp的socket服务,最好明确具体的地址和端口。这个对象在创建时,就已经可以对指定ip和端口进行连接(三次握手)。

2,如果连接成功,就意味着通道建立了,socket流就已经产生了。只要获取到socket流中的读取流和写入流即可,只要通过getInputStream和getOutputStream就可以获取两个流对象。

3,关闭资源。

class  TcpClient{

    public static voidmain(String[] args) throws Exception{

        Socket s = newSocket("192.168.1.100",10002);

        OutputStream out = s.getOutputStream();//获取了socket流中的输出流对象。

        out.write("tcp,哥们又来了!".getBytes());

        s.close();

    }

}

客户端:

1,创建服务端socket服务,并监听一个端口。

2,服务端为了给客户端提供服务,获取客户端的内容,可以通过accept方法获取连接过来的客户端对象。服务器可以连接多个客户端而能保证数据不会发错的原因就是,它用的是客户端的Socket流。

3,可以通过获取到的socket对象中的socket流和具体的客户端进行通讯。

4,如果通讯结束,关闭资源。注意:要先关客户端,再关服务端。

class  TcpServer{

    public static voidmain(String[] args) throws Exception{

        ServerSocket ss = newServerSocket(10002);//建立服务端的socket服务

        Socket s = ss.accept();//获取客户端对象

        String ip =s.getInetAddress().getHostAddress();//获取连接进来的客户端的IP地址

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

     //可以通过获取到的socket对象中的socket流和具体的客户端进行通讯。

        InputStream in = s.getInputStream();//读取客户端的数据,使用客户端对象的socket读取流

     //将获取的数据存放到一个字节数组中,有利于提高效率

        byte[] buf = new byte[1024];

        int len = in.read(buf);

        String text = new String(buf,0,len);

        System.out.println(text);

       // 如果通讯结束,关闭资源。

        s.close();

        ss.close();

    }

}

练习:服务端上传一张图片给服务端,服务端将其存入到一个文件中,存入成功给出一个反馈信息给客户端,表示上传成功。class PicSocket
{
public static void main(String[] args) throws Exception
{
Socket s=new Socket("192.168.1.100",10014);
FileInputStream fs=new FileInputStream("D:\\Media\\ZUOYE\\day24\\1.jpg");
       OutputStream fos=s.getOutputStream();
byte[] buf=new byte[1024];
int len=0;
while((len=fs.read(buf))!=-1)
{
fos.write(buf,0,len);
}

              //此处很关键,因为是阻塞式传输,如果客户端传送完数据没有给出一个标记表示文件已经传输完的话,服务端会一直等,所以服务端其实已经存入成功,但是没有给出“上传成功”的字样,初次遇到这种问题会很纠结,找不出原因。因此,客户端在上传时,当要上传的文件上传完时,一定要给一个信息让服务端知道。
s.shutdownOutput();


  InputStream fr=s.getInputStream();
byte[] buff=new byte[1024];
int leng=fr.read(buff);
System.out.println(new String(buff,0,leng));


fs.close();d
s.close();
}
}
class PicServer
{
public static void main(String[] args)throws Exception
{
ServerSocket ss=new ServerSocket(10014);
Socket s=ss.accept();
InputStream is=s.getInputStream();
FileOutputStream fos=new FileOutputStream("D:\\Media\\ZUOYE\\day24\\3.jpg");
byte[] buf=new byte[1024];
int len=0;
while((len=is.read(buf))!=-1)
{
fos.write(buf,0,len);
}
System.out.println(".......");
OutputStream os=s.getOutputStream();
os.write("上传成功".getBytes());


is.close();
s.close();
ss.close();
 
}
}

练习二,客户端从键盘录入中获取到的字符上传给服务端,服务端收到后再将其转换成大写反馈给客户端。

public class Tcp {


/**
* @param args
*/
//获取键盘录入,并将其传给服务端,服务接收到数据后再将其转换成大写返回给客户端。
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
         Socket s=new Socket("192.168.1.100",10003);
         BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
         PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
        BufferedReader bfr=new BufferedReader(new InputStreamReader(s.getInputStream()));
        //byte[]buf=new byte[1024];
         String line=null;
         while((line=br.readLine())!=null)
         {
        if("over".equals(line))
        break;
        pw.println(line);
        String str=bfr.readLine();
        System.out.println(str);
         }
         br.close();
         s.close();
}


}

public class TcpServer {


/**
* @param args
*/
public static void main(String[] args)throws Exception {
// TODO Auto-generated method stub
        ServerSocket ss=new ServerSocket(10003);
        Socket s=ss.accept();
        BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
        PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
      
        String line=null;
        while((line=br.readLine())!=null)
        {
        String str=line.toUpperCase();
        pw.println(str);
        
        }
        br.close();
        ss.close();
}


}

总结:在网络编程中一定要注意它的步骤,要明确每一个流程是怎么走的。就以上面这个键盘录入为例分析:

客户端:1,建立连接。

                 2,键盘录入,再将获取到的数据通过输出流发送到服务端。

                 3,要获取服务端反馈过来的信息,所以要有一个输入流来接收服务端发来的数据。

                 4,如果输出流用到了缓冲技术一定要每输完一行就要换行一次,并且刷新一次。

                  5,当读到有结束标记的语句时就停止读写的操作

                 6,关闭资源

服务端:1,建立连接。

                2,通过accept()的方法获取客户端的Socket。并通过它来获取客户端传过来的数据。

                3,每获取一行的数据,将其转换成大写再反馈给客户端,直至客户端结束传入数据。

                4,关闭资源。

---------------------- ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值