网络编程的总结


网络编程

网络模型

   OSI参考模型

   TCP/IP参考模型

   网络通讯要素

IP地址

    端口号

   传输协议

 

 

1、TCP:

|--特点:面向连接、虚电路连接、有缓冲的传输、全双工通信

|--对象:

|--Socket:用来建立发送       端建立Socket服务的对象,

|--ServerSocket:用来建立接收端建立Socket服务的对象。

因为只有当创建了Socket服务通道时,才能建立端点到端点的连接,进行数据通讯。

|--客户端和服务端建立连接:

|--客户端:

思路:

1、创建TCP的客户端socket服务,使用socket对象完成,建立在创建客户端对象时就明确服务端的端口

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

2、如果连接创建成功,因为这传输通道数据(IO)就已经有了,也就是网络IO流已经存在,获取网络IO流对象就可以了,既然是客户端发送数据给服务端,使用输出流。

OutputStream out=s.getOutputStream();

3、通过输出流对象的write方法写入到目的地,目的地就是连接的另一端。

Out.write("TCP哥们我来了".getBytes());

4、关闭资源

S.close();

 

演示tcp传输。


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


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


需求:给服务端发送给一个文本数据。

步骤:
1,创建Socket服务。并指定要连接的主机和端口。


import java.io.*;
import java.net.*;
class  TcpClient
{
 public static void main(String[] args) throws Exception
 {
  创建客户端的socket服务。指定目的主机和端口
  Socket s = new Socket("192.168.1.254",10003);
  
  为了发送数据,应该获取socket流中的输出流。
  OutputStream out = s.getOutputStream();

  out.write("tcp ge men lai le ".getBytes());
  s.close();
 }
}

 

TCP应用遇到的常见问题:

|--IO体系中四个明确中的明确设备中的网络:Socket.getInputStream和Socket.getOutputStream

|--在运行客户端和服务进行交互时,服务端和客户端都再等待,服务端等待的原因是accept方法,客户端等待是因为等待键盘录入,在日常我们最常见的阻塞式方法有read方法和readLine方法,readLine方法比较特殊,只有遇到结束标记换行时,才开始返回,不然它一直读取。

|--客户端录入不了?这就是TCP通讯中最容易产生的问题:等待,因为上面说到的阻塞式方法,因为写入到的数据是写进了缓冲区,并没有到目的地的服务端去,所以不要忘记刷新。

|--服务端读了还是没有数据,readLIne方法有读到,但是没有返回,这是readLine的特点,上面已经说到,只有读到结束标记的时才返回。所以要调用newLine()方法换行才可以。

|--怎么去让服务端知道客户发送数据结束,可是定义标记,比如说over,但是这样的方法是行不通的,当我们要发送的内容当中如果包含了over这样内容,服务端就会在此时中断接收,其实发送端还并没有发送结束,这时我们应该调用shutdownOutput方法即可。

|--改进:使用PrintWriter对象,它对换行操作的时候具备自动刷新功能。

 

文件上传:

原理:把一个个文件中的内容发送到服务端存储到一个文件中,这就是上传,上传成功后服务端会反馈给客户端:上传成功

客户端思路:

1、读取一个文本文件

2、定义目的是网络,将读取的数据发送到服务端。

实现代码:

Socket s=newSocket("192.168.1.104",10000);

BufferedReaderbuf=new BufferedReader(new FileReader("关联的文件"));

PrintWriterout=new PrintWriter(s.getOutputStream(),true);

Strringline=null;

While((line=bufr.readLine())!=null){

Out.println(line);

}

s.shutdownOutput();//告诉服务端客户端数据发送完毕,其实就是写入了标记。

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

Stringstr=bufIn.readLine();

Sop(str);

Bufr.close();

S.close();

服务端代码实现:

              ServerSocket ss = newServerSocket(10000);

              Socket s = ss.accept();

              System.out.println(s.getInetAddress().getHostAddress()+".....connected");

              BufferedReader bufIn=newBufferedReader(new InputStreamReader(s.getInputStream()));

              PrintWriter pw = newPrintWriter(new FileWriter("c:\\server.txt"),true);

              String line = null;

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

                     pw.println(line);

              }

              PrintWriter out = newPrintWriter(s.getOutputStream(),true);

              out.println("上传成功");

              pw.close();

              s.close();

              ss.close();     

       }

 

图片上传:

原理:张三首先登陆服务器,李四想要这时候进来的时候不能的,因为服务器所有的代码都再为张三服务,服务器端主要是三样技术:server Socket IO 多线程技术。所以服务端要使用多线程,才能保证多客户端访问。

其中要注意的细节:服务端要不断的接收数据,但是会名字相同的时候会覆盖,所以不能用固定的名称来命名,可以通过定义变量来记录。

服务端实现代码:

class PicThreadimplements Runnable {

       private Socket s;

       PicThread(Socket s){

              this.s  = s;

       }

       public void run() {

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

              try{

                     int count = 1;

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

                            InputStream in = s.getInputStream();

                           

                            File dir = newFile("c:\\pic");

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

                            while(file.exists()){

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

                            }

                            FileOutputStream fos= new FileOutputStream(file);

                            byte[] buf = newbyte[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){

                     e.printStackTrace();

                     throw newRuntimeException(ip+"... 上传失败");

                    

              }

       }

}

public classUploadPicServer {

       publicstatic void main(String[] args) throws IOException {     

              ServerSocket ss = newServerSocket(10006);           

              while(true){

                     Socket s = ss.accept();

                    

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

              }

       }

}

客户端实现代码:

stException, IOException {

              if(args.length!=1)

                     thrownew RuntimeException("请选择一个图片文件");

              Filefile = new File(args[0]);

              if(!file.exists())

                     thrownew RuntimeException("该文件不存在");

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

                     thrownew RuntimeException("必须是扩展名为jpg的文件"); 

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

                     thrownew RuntimeException("疯了吧!");       

              Sockets = new Socket("192.168.1.100",10006);

              FileInputStreamfis = new FileInputStream(file);

              OutputStreamout = s.getOutputStream();

              byte[]buf = new byte[1024];

              intlen = 0;

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

                     out.write(buf,0,len);

              }

       s.shutdownOutput();

              InputStreamin = s.getInputStream();

             

              byte[]bufIn = new byte[1024];

              intlenIn = in.read(bufIn);

              Stringstr = new String(bufIn,0,lenIn);

              System.out.println(str);

              fis.close();

              s.close();

       }

浏览器原理:

浏览器是一个客户端,给指定的服务端发送应用层http协议的消息头(是浏览器和服务器之间的规则,其中有

    请求行,以及支持的方式,以及客户的信息),

    他和服务端之间封装了socket对象。

    服务器底层是ServerSocket。

    向客户端发送html请求,

 

两种模式:

1、c/s:client/server

       早期开发流行,c++,

       特点:客户端和服务端,两端都需要程序员编写,程序员还得安装到用户,

           用户用对方开发的客户端,去连接对方开发的服务端,QQ 、360、  酒店管理系统等

        弊端:

            开发成本偏高,因为既要做客户端也要做服务端。

            维护成本高,如果用户要更新,就的拿去安装。

            由于网络带宽的提高可以进行网络更新了。

        好处:

            将部分运算分离到了客户端来完成?

            比如说360在本地查杀的时候运行的客户端。不需要去运行服务端。

        2、b/s:browser/server

        特点:

    程序员只需要开发服务端,客户端直接使用系统中已有的软件浏览器即可。

        好处:

        降低开发和维护成本。客户端什么都不用安装,直接使用系统安装的浏览器即可。

        弊端:

        所有的运算都在服务端。所以服务器压力相对较大。

 


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值