网络编程(3)TCP

来源:互联网 发布:淘宝蚂蚁花呗激活教程 编辑:程序博客网 时间:2024/06/08 12:58

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上传文本//源--FileReaderBufferedReader 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.outString 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()));//目的 FileWriterPrintWriter 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.jpgif(!(file.getName().endsWith(".jpg") || file.getName().endsWith(".gif"))){JOptionPane.showMessageDialog(null, "只允许上传jpg或gif格式!");return;}if(file.length()>=1024*1024*2){//大于2MJOptionPane.showMessageDialog(null, "文件大小不能超过2M!");return;}//经过上面的防护,要上传的文件对象file是合法的try {Socket s = new Socket("127.0.0.1",10001);//源: file--字节流  FileInputStreamFileInputStream fin = new FileInputStream(file);//目的: socket--outputStreamOutputStream 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;}@Overridepublic 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>


 

 

0 0