socket 实现网络互动

在写 socket 之前先给大家介绍下 TCP 和 UDP
TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它提供的服务包括数据流传送、可靠性、有效流控、全双工操作和多路复用。通过面向连接、端到端和可靠的数据包发送。通俗说,它是事先为所发送的数据开辟出连接好的通道,然后再进行数据发送;而UDP则不为IP提供可靠性、流控或差错恢复功能。

面向连接的TCP
“面向连接”就是在正式通信前必须要与对方建立起连接。比如你给别人打电话,必须等线路接通了、对方拿起话筒才能相互通话。

TCP协议能为应用程序提供可靠的通信连接,使一台计算机发出的字节流无差错地发往网络上的其他计算机,对可靠性要求高的数据通信系统往往使用TCP协议传输数据。

面向非连接的UDP协议
“面向非连接”就是在正式通信前不必与对方先建立连接,不管对方状态就直接发送。与手机短信非常相似:你在发短信的时候,只需要输入对方手机号就OK了。

UDP(User Data Protocol,用户数据报协议)是与TCP相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去!

TCP与UDP区别总结:

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)
4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

UDP如何实现可靠传输

由于在传输层UDP已经是不可靠的连接,那就要在应用层自己实现一些保障可靠传输的机制

简单来讲,要使用UDP来构建可靠的面向连接的数据传输,就要实现类似于TCP协议的

超时重传(定时器)
有序接受 (添加包序号)
应答确认 (Seq/Ack应答机制)
滑动窗口流量控制等机制 (滑动窗口协议)

等于说要在传输层的上一层(或者直接在应用层)实现TCP协议的可靠数据传输机制,比如使用UDP数据包+序列号,UDP数据包+时间戳等方法。

java 代码实现 tcp

服务端server

public class UploadServer {

  public static void main(String[] args) throws IOException {
    //1.创建一个ServerSocket
    ServerSocket serverSocket = new ServerSocket(8888);     
    
    //2.使用ServerSocket监听用户的请求
    Socket socket = serverSocket.accept();      
    
    //3.接收用户的请求数据并复制到本地
    //创建流(输入流和输出流)
    BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:/women2.mp3"));
    //使用流(输入流和输出流)
    byte [] buf = new byte[1024];
    int len = bis.read(buf);
    while(len !=-1){
        //写一个字节
        bos.write(buf, 0, len);
        //输出
        //System.out.println((char)n);
        //读一个字节
        len = bis.read(buf);
    }       
    //手动刷新(输出缓冲区内容写入文件)
    //bos.flush();
    //关闭流(输入流和输出流)
    //bis.close(); //关闭流同时关闭socket
    socket.shutdownInput();
    bos.close();
    
    //4.给客户端响应(上传成功)
    BufferedOutputStream bos2 = new BufferedOutputStream(socket.getOutputStream());
    bos2.write("上传成功".getBytes());
    bos2.flush();
    //5.关闭资源
    bis.close();
    bos2.close();
    socket.close();
    serverSocket.close();

  }
}

客户端client

public class UploadClient {

public static void main(String[] args) throws UnknownHostException, IOException {
    //1.创建一个Socket,连接服务器端
    Socket socket = new Socket(InetAddress.getLocalHost(), 8888);       
    
    //2.复制文件到服务器端
    //创建流(输入流和输出流)
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("d:/women.mp3")));
    BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
    //使用流(输入流和输出流)
    byte [] buf = new byte[1024];
    int len = bis.read(buf);
    while(len !=-1){
        //写一个字节
        bos.write(buf, 0, len);
        //输出
        //System.out.println((char)n);
        //读一个字节
        len = bis.read(buf);
    }       
    //关闭流(输入流和输出流)
    bis.close();
    //bos.close();
    socket.shutdownOutput(); //只想关闭输出流,但是不想同时关闭socket
    //3.接收响应信息并输出
    BufferedInputStream bis2 = new BufferedInputStream(socket.getInputStream());
    len = bis2.read(buf);
    System.out.println(len);
    System.out.println(new String(buf,0,len));
    //4.关闭资源
    bos.close();
    socket.close();
}

}

java 代码实现 udp

服务端 server 代码

public class AskServer {
  public static void main(String[] args) throws IOException, ClassNotFoundException {
    //1.创建一个DatagramSocket,用来发送或者接收数据
    DatagramSocket socket = new DatagramSocket(8888);//8888  接收数据的端口        
    
    //2.使用DatagramSocket接收数据
    byte [] buf = new byte[1024];
    DatagramPacket packet = new DatagramPacket(buf, buf.length);        
    socket.receive(packet); 
    //System.out.println("客户端发来的消息:"+new String(packet.getData(),0,packet.getLength()));
    ByteArrayInputStream bais = new ByteArrayInputStream(packet.getData(), 0, packet.getLength());
    ObjectInputStream ois = new ObjectInputStream(bais);
    //System.out.println(ois.readInt());
    //System.out.println(ois.readDouble());
    System.out.println(ois.readObject());
        
    //3.使用DatagramSocket发送数据
    String  reply = "你在线吗?";
    byte [] buf2 =reply.getBytes();
    DatagramPacket packet2 = new DatagramPacket(buf2, buf2.length, packet.getAddress(), packet.getPort());
    socket.send(packet2);
    
    //4.关闭资源
    ois.close();
    socket.close();     
  }
}

客户端client 代码

public class AskClient {

  public static void main(String[] args) throws IOException {
    //1.创建一个DatagramSocket,用来发送或者接收数据
    DatagramSocket socket = new DatagramSocket(9999);//接收数据的端口
    
    //2.使用DatagramSocket发送数据
    //int num = 10;
    //double pi=3.14;
    User user = new User("liao","xiong");
    //各种数据类型------> byte [] 
    //// start!!!!
    ByteArrayOutputStream  baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    //oos.writeInt(num);
    //oos.writeDouble(pi);
    oos.writeObject(user);
    byte [] buf = baos.toByteArray();
    /////end!
    DatagramPacket packet = new DatagramPacket(buf, buf.length, InetAddress.getLocalHost(), 8888);
    socket.send(packet);
    
    //3.使用DatagramSocket接收数据
    byte [] buf2 = new byte[1024];
    DatagramPacket packet2 = new DatagramPacket(buf2, buf2.length);     
    socket.receive(packet2);
    System.out.println("服务器端的反馈:"+new String(buf2,0,packet2.getLength()));
    
    //4.关闭资源
    oos.close();
    socket.close();
  }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容

  • 本章讨论TCP/IP体系中运输层最重要的两种协议:UDP和TCP。必须弄清TCP的各种机制(如面向连接的可靠服务、...
    dmmy大印阅读 936评论 0 0
  • 个人认为,Goodboy1881先生的TCP /IP 协议详解学习博客系列博客是一部非常精彩的学习笔记,这虽然只是...
    贰零壹柒_fc10阅读 5,054评论 0 8
  • 文/郭同学啊 01. 你不知道的是:“有那么一个卑微的女孩曾经那样深深地喜欢过你”。 吴桐,请原谅我这样直接称呼你...
    郭同学啊阅读 294评论 0 1
  • 【0529今日话题】 你看过的,最美丽的风景是什么?(欢迎图片,哈哈,但最好不要只是图片) 从我家后门拍的。五月早...
    梓毓爸阅读 149评论 0 1
  • 20岁 走在社会上 有时候会遇到一些心仪的人 可是不敢上前 没有身材 没有才华 我只不过是一个普通再普通不过的人 ...
    旧时光Fade阅读 171评论 0 1