网络编程(3)TCP

    xiaoxiao2024-12-30  22

    TCP SocketIP地址和端口,套接字

         •SocketServerSocket      •建立客户端和服务器端      •建立连接后,通过Socket中的IO流进行数据的传输      •关闭socket          

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

     

    TCP传输编程

    基本思路(客户端)

         •客户端需要明确服务器的ip地址以及端口,这样才可以去试着建立连接,如果连接失败,会出现异常。      •连接成功,说明客户端与服务端建立了通道,那么通过IO流就可以进行数据的传输,而Socket对象已经提供了输入流和输出流对象,通过getInputStream(),getOutputStream()获取即可。      •与服务端通讯结束后,关闭Socket

    基本思路(服务器端)

        •服务端需要明确它要处理的数据是从哪个端口进入的。     •当有客户端访问时,要明确是哪个客户端,可通过accept()获取已连接的客户端对象,并通过该对象与客户端通过IO流进行数据传输。     •当该客户端访问结束,关闭该客户端。

    基于TCPSocket通信流程

    TCP传输编程

    客户端

        通过Socket建立对象并指定要连接的服务端主机以及端口。

    <span style="font-family:Times New Roman;font-size:14px;">Socket s = new Socket(“192.168.1.1”,9999); OutputStream out = s.getOutputStream(); out.write(“hello”.getBytes()); s.close(); </span>

     

    服务器端

         建立服务端需要监听一个端口

    <span style="font-family:Times New Roman;font-size:14px;">ServerSocketss = new ServerSocket(9999); Socket s = ss.accept (); InputStream in = s.getInputStream(); byte[] buf = new byte[1024]; intnum = in.read(buf); String str = new String(buf,0,num); System.out.println(s.getInetAddress().toString()+”:”+str); s.close(); ss.close(); </span>

     

    思考

          对于Web服务器而言,当有多个客户端同时访问服务器时,服务端又如何提供服务呢?

    TCP传输最容易出现的问题

        •客户端连接上服务端,两端都在等待,没有任何数据传输。     •通过例程分析:     –因为read方法或者readLine方法是阻塞式。     •解决办法:    –自定义结束标记    –使用shutdownInputshutdownOutput方法。

    编程练习

       ☆上传文本文件

             读取一个本地文本文件,将数据发送到服务端,服务器端对数据进行存储。存储完毕后,给客户端一个提示。

    Client:

    <span style="font-family:Times New Roman;font-size:14px;color:#000000;">package cn.hncu.net.tcp.uploadTxt; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; public class UploadTxtClient { public static void main(String[] args) { try { Socket s = new Socket("192.168.2.100",10000); //1上传文本 //源--FileReader BufferedReader br = new BufferedReader( new FileReader("upload/client.txt") ); //目的 socket---OutputStream //BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( s.getOutputStream() )); //建议用打印流 PrintWriter pw = new PrintWriter( s.getOutputStream(), true ); String line = null; while( (line=br.readLine())!=null){ pw.println(line); } //pw.println("over!");//发送自定义的结束标记---有隐患,如果所上传文件中包含该结束标记,就会有问题! //得告诉服务器:上传数据结束 s.shutdownOutput(); //2读取服务器的应答消息 //源socket--s.getInputStream() 字节流 BufferedReader br2 = new BufferedReader( new InputStreamReader( s.getInputStream()) ); //目的显示屏System.out String txt = br2.readLine(); System.out.println("server应答:"+ txt); s.close(); } catch (IOException e) { e.printStackTrace(); } } } </span>

    Server

    <span style="font-family:Times New Roman;font-size:14px;">package cn.hncu.net.tcp.uploadTxt; import java.io.BufferedReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; public class UploadTxtServer { public static void main(String[] args) { try { ServerSocket ser = new ServerSocket(10000); while(true){ Socket s = ser.accept(); //接收上传的文件 //源 socket--字节流 -->字符流 且 带缓存 BufferedReader br = new BufferedReader( new InputStreamReader(s.getInputStream())); //目的 FileWriter PrintWriter pw = new PrintWriter( new FileWriter("upload/server.txt"),true); String line = null; while( (line=br.readLine())!=null ){ // if("over!".equals(line)){ // break; // } pw.println(line); } //发送应答消息 PrintWriter pw2 = new PrintWriter(s.getOutputStream(),true); pw2.println("上传成功"); s.close(); } } catch (IOException e) { e.printStackTrace(); } } } </span>

       ☆上传图片文件

            客户端需求:把一个图片文件发送到服务端并读取回馈信息。要求判断文件是否存在及格式是否为jpggif并要求文件小于2M

            服务端需求:接收客户端发送过来的图片数据。进行存储后,回馈一个上传成功字样。支持多用户的并发访问。

    Client:

    <span style="font-family:Times New Roman;font-size:14px;color:#000000;">package cn.hncu.net.tcp.uploadPic; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; import javax.swing.JFileChooser; import javax.swing.JOptionPane; public class UploadPicClient { public static void main(String[] args) { JFileChooser jfc = new JFileChooser(); int res = jfc.showOpenDialog(null); if(res!=JFileChooser.APPROVE_OPTION ){ return; } File file = jfc.getSelectedFile(); if(!file.exists()){ JOptionPane.showMessageDialog(null, "该文件不存在"); return; } //dsj.gif.ext a.jpg.txt aa.txt.jpg if(!(file.getName().endsWith(".jpg") || file.getName().endsWith(".gif"))){ JOptionPane.showMessageDialog(null, "只允许上传jpg或gif格式!"); return; } if(file.length()>=1024*1024*2){//大于2M JOptionPane.showMessageDialog(null, "文件大小不能超过2M!"); return; } //经过上面的防护,要上传的文件对象file是合法的 try { Socket s = new Socket("127.0.0.1",10001); //源: file--字节流 FileInputStream FileInputStream fin = new FileInputStream(file); //目的: socket--outputStream OutputStream out = s.getOutputStream(); byte buf[] = new byte[1024]; int len=0; while( (len=fin.read(buf))!=-1 ){ out.write(buf, 0, len); } //告诉服务器,发送完毕 s.shutdownOutput(); //读取服务器的应答 InputStream in = s.getInputStream(); byte buf2[] = new byte[512]; int len2 = in.read(buf2); System.out.println( new String(buf2,0,len2)); //关流 in.close(); fin.close(); out.close(); s.close(); } catch (IOException e) { e.printStackTrace(); } } } </span>

    Server:

    <span style="font-family:Times New Roman;font-size:14px;color:#000000;">package cn.hncu.net.tcp.uploadPic; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; public class UploadPicServer { public static void main(String[] args) { try { ServerSocket ser = new ServerSocket(10001); while(true){ Socket s = ser.accept(); new Thread( new UploadThread(s) ).start(); } } catch (IOException e) { e.printStackTrace(); } } } class UploadThread implements Runnable{ private Socket s = null; public UploadThread( Socket s){ this.s = s; } @Override public void run() { String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+".......connected..."); try { File dir = new File("pics"); if(!dir.exists()){ dir.mkdir(); } File file = new File(dir,ip+".jpg"); int count=1; while(file.exists()){ file = new File(dir,ip+"("+ (count++) +").jpg"); } InputStream in = s.getInputStream(); FileOutputStream fout = new FileOutputStream(file); byte buf[] = new byte[512]; int len=0; while( (len=in.read(buf))!=-1){ fout.write(buf, 0, len); } //给客户端应答消息 s.getOutputStream().write( "上传成功".getBytes() ); fout.close(); s.close(); } catch (IOException e) { e.printStackTrace(); } } } </span>

     

     

    转载请注明原文地址: https://ju.6miu.com/read-1295141.html
    最新回复(0)