黑马程序员—网络编程之TCP

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

网络编程TCP

Tcp传输

  1tcp分客户端和服务端

  2、客户端对应的对象是Socket  服务器端对应的对象是ServerSocket

客户端

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

步骤:

  1、创建Socket服务,并指定要连接的主机和端口

  2、获取Socket中输出流

  3、发送数据

  4、关闭客户端

 

给服务器端发送一段数据

publicclass TcpClient {

 

    publicstaticvoid main(String[] args)throws Exception

    {

       //创建客户端的Socket服务,指定目的主机和端口

       Socket s = new Socket(InetAddress.getByName("192.168.137.165"),10000);

       //为了发送数据,应该获取Socket流中的输出流

       OutputStream os = s.getOutputStream();

       os.write("lsk is on the way!".getBytes());

       //关闭客户端服务

       s.close();

 

    }

}

服务器端:

  1、建立服务器端的Socket服务,ServerSocket()  并监听一个端口

  2、获取连接过来的客户端对象

     通过ServerSocket的accept方法,没有连接就会等,所以这个方法阻塞式的

  3、客户端如果发过来数据,那么服务器端要使用对应的客户端队象,并获取到该客户端

     对象的的读取流来读取发过来的数据

  4、关闭服务器端

 

publicclass TcpServer {

 

    publicstaticvoid main(String[] args)throws Exception

    {

       //建立服务器端Socket服务,并监听一个端口

       ServerSocket ss = new ServerSocket(10000);

       //通过accept方法获取连接过来的客户端对象

       Socket s = ss.accept();

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

       System.out.println(ip+"connecting!");

       //获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据

       InputStream in = s.getInputStream();

       byte[] buf =newbyte[1024];

       in.read(buf);

        System.out.println(new String(buf,0,buf.length));

       s.close();

    }

 

}

 

下面以同时上传多张图片为例说明TCP传输

服务端

 单线程的服务端有个局限性,当A客户端连接上以后,被服务器端获取到,服务端执行具体流程,这是B客户端只能等待。 因为服务器端还没有处理完A客户端的请求,还没没有回来执行循环方法。所以暂时获取不到B客户端的对象,那么为了可以让多个客户端同时并发访问服务器,服务器端最好是将每个客户端封装到一个单独的线程中,这样可以同时处理多个客户端请求。

 如何定义线程呢? 只要明确了每个客户端在服务器执行的代码即可,将该代码存入run方法中

class ImgThreadimplements Runnable

{

    //定义socket服务

    private Sockets;

    public ImgThread(Socket s)

    {

       this.s = s;

    }

    publicvoid run()

    {

       try

       {

           //命名接收到的图片时使用的变量

           int count = 1;

          

           //获得发送端的IP地址

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

          

           System.out.println(ip+"connecting、、、");

          

           //创建图片文件

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

          

           //如果文件存在,count就加一,保证文件不重名

           while(file.exists())

           {

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

           }

      

           //获得Socket的输入流

           InputStream is = s.getInputStream();

          

           //创建文件输出流,把上传的文件写入指定文件

           FileOutputStream fos =new FileOutputStream("lsk_copy.jpg");

          

           byte[] buf =newbyte[1024];

          

           int len = 0;

          

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

           {

              fos.write(buf,0,len);

           }

          

           //获得socket的输出流,向客户端写数据

           OutputStream os = s.getOutputStream();

          

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

          

           //关闭输出流

           fos.close();

          

           //关闭服务

           s.close();

       }

       catch(Exception e)

       {

           thrownew RuntimeException("上传失败");

       }

    }

   

}

 

 

publicclass TcpImgServer

{

 

    publicstaticvoid main(String[] args)throws Exception

    {

       //创建tcp服务端并指定端口

       ServerSocket ss = new ServerSocket(10001);

      

       //循环接收上传的图片

       while(true)

       {

           Socket s = ss.accept();

          

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

          

       }

       //ss.close();

    }

}

客户端

   1、服务端点

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

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

   4、读取服务器反馈信息

   5、关闭

publicclass TcpImgClient

{

    publicstaticvoid main(String[] args)throws Exception

    {

       //创建发送端服务

       Socket s = new Socket("127.0.0.1",10001);

      

       //指定上传的图片文件

       FileInputStream fis = new FileInputStream("C:/Users/Administrator/Desktop/刘少康.jpg");

      

       //获得socket的输出流

        OutputStream os = s.getOutputStream();

             

       //定义字节数组

       byte[] buf =newbyte[1024];

      

       int len = 0;

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

       {

           os.write(buf,0,len);

       }

       //告诉服务器端数据已写完

       s.shutdownOutput();

      

       //获得socket的输入流

       InputStream is = s.getInputStream();

      

       //定义字节数组存放接收的数据

       byte[] bufin =newbyte[1024];

      

       int len1 = is.read(bufin);

      

       System.out.println(new String(bufin,0,len1));

      

      

    }

}

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值