网络编程TCP&UDP基础总结

来源:互联网 发布:透视眼软件 编辑:程序博客网 时间:2024/05/16 06:51

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

1、TCP:

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

|--对象:

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

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

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

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

|--客户端:

思路:

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

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

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

OutputStream out=s.getOutputStream();

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

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

4、关闭资源

s.close();

|--服务端:

思路:

1、创建TCP的服务端Socket对象ServerSocket,必须分配一个数字标示(端口),必须去监听一个端口,以便可以处理来自这个端口的数据。

2、使用从客户端获取的流对象来完成数据的传输,既然是获取客户端数据,只要获取socket流中的读取流即可。

InputStream in=s.getInputStream();

3、将数据打印在控制台上,并带上IP地址

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

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

4、关闭资源。

S.close();

Ss.close();

|--客户端和服务端简单交互:

|--客户端:

实现代码:

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

OutputStream out=s.getOutputStream();

out.write("".getBytes());

InputStream  in=s.getInputStream();

Byte[] buf=new byte[1024];

Int len=in.read(buf);

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

System.out.println(str);

s.close();


|--服务端:

实现代码:

ServerSocket ss=new ServerSocket(9999);

Socket s=ss.accept();

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

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

//读取客户端发来的数据

InputStream in=s.getInputStream();

Byte[] buf=new Byte[1024];

Int len=in.read(buf);

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

System.out.println(str);

//给客户端一个反馈

OutputStream, out=s.getOutputStream();

out.write();

S.close();

Ss.close();

 

2、TCP应用遇到的常见问题:

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

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

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

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

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

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

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

 

 

3、文件上传:

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

客户端思路:

1、读取一个文本文件

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

实现代码:

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

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

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

Strring line=null;

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

out.write(line);

}

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

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

String str=bufIn.readLine();

System.out.println(str);

buf.close();

s.close();

服务端代码实现:

              ServerSocketss = new ServerSocket(9999);

              Sockets = ss.accept();

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

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

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

              Stringline = null;

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

                     pw.println(line);

              }

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

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

              pw.close();

              s.close();

              ss.close();     

       }

 

 

4、图片上传:

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

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

服务端实现代码:

class PicThread implements 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 = new File("c:\\pic");

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

                            while(file.exists()){

                                   file = newFile(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(IOExceptione){

                     e.printStackTrace();

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

                    

              }

       }

}

public classUploadPicServer {

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

              ServerSocketss = new ServerSocket(10006);           

              while(true){

                     Socket s = ss.accept();

                    

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

              }

       }

}

 

客户端实现代码:

stException, IOException {

              if(args.length!=1)

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

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

              if(!file.exists())

                     throw new RuntimeException("该文件不存在");

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

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

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

                     throw new RuntimeException("疯了吧!");       

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

              FileInputStream fis = newFileInputStream(file);

              OutputStream out = s.getOutputStream();

              byte[] buf = new byte[1024];

              int len = 0;

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

                     out.write(buf,0,len);

              }

       s.shutdownOutput();

              InputStream in = s.getInputStream();

             

              byte[] bufIn = new byte[1024];

              int lenIn = in.read(bufIn);

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

              System.out.println(str);

             

              fis.close();

              s.close();

       }

5、浏览器原理:

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

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

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

    服务器底层是ServerSocket。

    向客户端发送html请求,

 

 

 

 

 

6、两种模式:

1、c/s:client/server

       早期开发流行,c++,

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

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

        弊端:

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

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

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

        好处:

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

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

        2、b/s:browser/server

        特点:

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

        好处:

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

        弊端:

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



0 0
原创粉丝点击