您的位置:首页 > 理论基础 > 计算机网络

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

2015-12-17 21:45 741 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

TCP协议

        TCP(Transmission Control Protocol, 传输控制协议)是整个TCP/IP协议族中最重要的协议之一。它在IP提供的不可靠数据服务的基础上为应用程序提供了一个可靠的、面向连接的、全双工的数据传输服务。

TCP实现可靠性的方式

         最重要的是TCP采用了重发(retransmission)技术,即在传输过程中,发送方启动一个定时器,然后将数据包发出,当接收方收到这个信息时就给发送方一个确认(acknowledgelment)信息。如果发送方在定时器到点之前没有收到这个信息,就重新发送这个数据包。

利用TCP在源主机和目的主机之间建立和关闭连接操作时,均需要通过三次握手来确认建立和关闭是否成功。TCP建立连接的三次握手过程如下:

    1.源主机发送一个SYN(同步)标志位为1的TCP数据包,表示想与目标主机进行通信,并发送一个同步序列号(如SEQ=200)进行同步;

    2.目标主机同意进行通信,则响应一个确认(ACK位置1),并以下一个序列号为参考进行确认(如201);

    3.源主机以确认来响应目标主机的TCP包,这个确认中包括它想要接收的下一个序列号(该帧可以含有发送的数据)。至此连接建立完成。

     同样,关闭连接也需要进行三次握手。

     总之,TCP虽然提供了一个可靠的数据传输服务,但它是以牺牲通信量来实现的。也就是说,为了完成同样一个任务,TCP需要更多的时间和通信量。这在网络不可靠的时候通过牺牲一些时间来达到网络的可靠性是可行的,但在网络十分可靠的情况下,则可以采用UDP,通信量的浪费就会小很多。例如:必须支持交互式会话的应用程序(如FTP等)往往使用TCP,而自己进行错误检测或不需要进行错误检测的程序(如DNS,SNMP等)往往使用UDP。

     下面,我们用一个示例来演示,该示例完成了客户端向服务器端上传文件的功能。其中,服务器端为多线程,可以允许多个用户同时上传文件,上传的文件统一保存在文件夹upload中。代码如下:

客户端:import java.io.*;
import java.net.*;
import java.util.*;
public class TCP_UploadClient{
public static void main(String[] args)throws Exception{
//1.提示输入要上传的文件路径,验证路径是否存在以及是否是文件夹
File file = getFile();
//2.发送文件名到服务器
Socket socket = new Socket("127.0.0.1",12345);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream pw = new PrintStream(socket.getOutputStream());
pw.println(file.getName());
//3.接收结果,如果存在给予提示,程序直接退出
String result = br.readLine();
if(result.equals("存在")){
System.out.println("文件已经存在,请不要重复上传");
socket.close();
return;
}
//4.如果不存在,定义FileInputStream读取文件,写出到网络
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
int len = 0;
while((len=bis.read())!=-1)
pw.write(len);
bis.close();
socket.close();
}

private static File getFile(){
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个文件路径:");
while(true){
String str = sc.nextLine();
File f = new File(str);
if(!f.exists())
System.out.println("您录入的文件不存在");
else if(f.isDirectory())
System.out.println("您录入的是文件目录");
else
return f;
}
}
}

服务器端:
import java.io.*;
import java.net.*;
public class TCP_UploadServer{
public static void main(String[] args)throws Exception{
//1.建立多线程的服务器
ServerSocket ss = new ServerSocket(12345);
System.out.println("启动服务器,绑定12345端口");
//2.读取文件名
while(true){
final Socket socket = ss.accept();
new Thread(){
public void run(){
try{
InputStream is = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
PrintStream pw = new PrintStream(socket.getOutputStream());
String fileName = br.readLine();
//3.判断文件是否存在,将结果发回客户端
File dir = new File("upload");//创建一个文件夹,用来保存上传文件
dir.mkdir();
File file = new File(dir,fileName);
if(file.exists()){
pw.println("存在");
socket.close();
return;
}else{
pw.println("不存在");
}
//4.定义FileOutputStream,从网络读取数据,存储到本地
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
int len = 0;
while((len=is.read())!=-1)
bos.write(len);
bos.close();
socket.close();
}catch(IOException e){
throw new RuntimeException("读取失败");
}
}
}.start();
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息