摘要:进行TCP协议网络程序的编写,关键在于ServerSocket套接字的熟练使用,TCP通信中所有的信息传输都是依托ServerSocket类的输入输出流进行的。

本文分享自华为云社区《Java利用TCP协议实现客户端与服务器通信【附通信源码】》,作者:灰小猿。

TCP协议概念

我们知道TCP是可靠而非安全的网络协议。它可以保证数据在从一端送至另一端的时候可以准确的送达,并且抵达的数据的排列顺序和送出时的顺序是相同的。因此在进行TCP协议通信的时候,我们首先应该保证客户端和服务器之间的连接通畅。

而TCP协议程序的编写,仍然是依靠套接字Socket类来实现的,并且利用TCP协议进行通信的两个程序之间是有主次之分的,即一个是服务器的程序,另一个是客户端的程序。因此两者的功能和编写上也略有不同。如下图是服务器与客户端之间进行通信的示意图:

以上就是在TCP协议中客户端与服务器建立连接的过程示意图。而在这其中起到关键作用的就是服务器端套接字ServerSocket和客户端套接字Socket。通过这两个套接字来建立服务器和客户端,从而利用其中的函数进行数据的通信。

在ServerSocket类中有很多需要注意的地方,接下来大灰狼和大家分享一下ServerSocket类的具体用法:

ServerSocket类

ServerSocket类存在于http://Java.net包中,表示服务器端的套接字,在使用时需要首先导入这个类,我们也知道ServerSocket类的主要功能就是通过指定的端口等待来自于网络中客户端的请求并且进行连接。

值得注意的是:服务器套接字一次只能与一个客户端套接字进行连接,因此如果存在多台客户端同时发送连接请求,则服务器套接字就会将请求的客户端存放到队列中去,然后从中取出一个套接字与服务器建立的套接字进行连接,但是服务器端能够容纳的客户端套接字也不是无限的,当请求连接的数量大于最大容纳量时,那么多出来的请求就会被拒接,一般来说队列的默认大小是50。

ServerSocket类的构造方法通常会抛出IOException异常,具体有以下几种形式:

  • ServerSocket():创建非绑定服务器套接字
  • ServerSocket(inr port):创建绑定到特定端口的服务器套接字
  • ServerSocket(int port, int backlog):利用指定的backlog创建服务器套接字,并将其绑定到指定的服务器端口上,
  • ServerSocket(int port, int backlog, InetAddress bindAddress):使用指定的端口,侦听backlog和要绑定到本地的IP地址创建服务器。这种情况适用于计算机上有多个网卡和多个IP地址的情况,用户可以明确的规定ServerSocket在哪块网卡或哪个IP地址上等待用户的连接请求。

以下是ServerSocket类中一些常用的方法:

了解了ServerSocket类的基本方法之后,就是如何进行客户端和服务器进行连接的问题了。

在服务器端我们可以调用ServerSocket类的accpet()方法与请求连接的客户机建立连接,这时会返回一个和客户端相连接的Socket对象,这个时候其实已经连接成功了,使用getInetAddress()方法就可以获取到进行请求的客户机的IP地址。

对于如何进行客户端和服务器端数据的通信,就要用到数据的输入流和输出流了,服务器端的Socket对象使用getOutputStream()方法获取到的输出流,将指向客户端的Socket对象使用getInputStream()方法获取到的输入流。由此就实现在服务器向客户端发送数据的一个过程,同样的道理,客户端端的Socket对象使用getOutputStream()方法获取到的输出流,将指向服务器端的Socket对象使用getInputStream()方法获取到的输入流。从而实现由客户端向服务器发送数据的过程。

注意:accpet()方法会阻塞线程的继续执行,如果在对应的接口没有收到客户端的呼叫,则程序会停留在此处,直到获取到客户端的呼叫才会继续向下执行,但是如果服务器没有收到来自客户端的呼叫请求,并且accpet()方法没有发生阻塞,那么通常情况下就是程序出了问题,一般来说可能是使用了一个已经被其他程序占用了的端口号,导致ServerSocket没有绑定成功!遇到这种情况可以尝试更换新的端口号。

了解了TCP协议的通信过程,接下来就是进行TCP通信程序的书写啦!

在网络通信中,如果只要求客户机向服务器发送信息,不要求服务器向客户端反馈信息的行为称为“单向通信”,要求客户机和服务器双方互相通信的过程称为“双向通信”,双向通信只不过是比单向通信多了一个服务器向客户端发送消息的过程,

接下来分别是服务器端和客户端程序的编写:

服务器端程序

package server_1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class MyTcp {private ServerSocket server;    //设置服务器套接字private Socket client;        //设置客户端套接字//连接客户端函数void getServer(){try {server = new ServerSocket(1100);  //建立服务器 端口为1100System.out.println("服务器建立成功!正在等待连接......");client = server.accept();   //调用服务器函数对客户端进行连接           System.out.println("客户端连接成功!ip为:" + client.getInetAddress());  //返回客户端IP       getClientMessage();     //调用信息传输和接收函数} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}void getClientMessage(){try {while (true) {InputStream is = client.getInputStream(); //获取到客户端的输入流byte[] b = new byte[1024]; //定义字节数组int len = is.read(b);  //由于信息的传输是以二进制的形式,所以要以二进制的形式进行数据的读取String data = new String(b, 0,len);System.out.println("客户端发来消息:" + data);//定义发送给客户端的输出流OutputStream put = client.getOutputStream();String putText = "我已经收到!欢迎你!";put.write(putText.getBytes());  //将输出流信息以二进制的形式进行写入}} catch (Exception e) {// TODO: handle exception}try {//判断客户端字节流不是空,则关闭客户端if (server != null) {server.close();}} catch (Exception e) {// TODO: handle exception}}public static void main(String[] args) {// TODO Auto-generated method stubMyTcp myTcp = new MyTcp();  //调用该类生成对象myTcp.getServer();    //调用方法}}

客户端程序

package client_1;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;public class MyClient {private Socket client;  //定义客户端套接字//建立客户端函数void getClient(){try {client = new Socket("127.0.0.1", 1100); //建立客户端,使用的IP为127.0.0.1,端口和服务器一样为1100System.out.println("客户端建立成功!");setClientMessage();      //调用客户端信息写入函数} catch (UnknownHostException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}//定义客户端信息写入函数void setClientMessage(){try {        OutputStream pt = client.getOutputStream();        //建立客户端信息输出流String printText = "服务器你好!我是客户端!"; pt.write(printText.getBytes());     //以二进制的形式将信息进行输出InputStream input = client.getInputStream();   //建立客户端信息输入流byte [] b = new byte[1024];        //定义字节数组int len = input.read(b);   //读取接收的二进制信息流String data = new String(b, 0,len);System.out.println("收到服务器消息:" + data);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {//如果客户端信息流不为空,则说明客户端已经建立连接,关闭客户端if (client != null) {client.close();}} catch (Exception e) {// TODO: handle exception}}public static void main(String[] args) {// TODO Auto-generated method stub//生成客户端类对象MyClient myClient  = new MyClient();myClient.getClient();}}

同时要注意:在客户端和服务器搭建成功之后,应该先打开服务器等待连接,再打开客户端进行连接,同样在进行关闭时,应该先关闭客户端,再关闭服务器。

以上面程序为例:

打开服务器等待客户端连接

打开客户端与服务器连接成功,并且实现双向通信:

注意:当一台机器上安装了多个网络应用程序时,很可能指定的端口已经被占用,甚至还可能遇到之前运行很好的程序突然卡住的情况,这种情况很可能是端口被别的程序占用了,这时可以运行netstat-help来活的帮助,可以使用命令netstat-an来查看该程序所使用的端口。

点击关注,第一时间了解华为云新鲜技术~

如何使用TCP/IP开发网络程序相关推荐

  1. Linux C : TCP/IP 和 网络编程

    目录 一.IP主机和IP地址 二.IP数据包格式 三.TCP/IP在网络中的数据流 四.套接字编程 4.1 创建套接字 4.2绑定socket和端口号 4.3.UDP 套接字 4.4 TCP 套接字 ...

  2. OSI七层网络结构图与TCP/IP五层网络结构图

    一. OSI七层网络结构图与TCP/IP五层网络结构图 又称<OSI七层网络模型与TCP/IP四层网络模型>. (1)OSI七层模型 OSI中的层 功能 TCP/IP协议族 应用层 文件传 ...

  3. 网络知识梳理--OSI七层网络与TCP/IP五层网络架构及二层/三层网络

    作为一个合格的运维人员,一定要熟悉掌握OSI七层网络和TCP/IP五层网络结构知识. 废话不多说!下面就逐一展开对这两个网络架构知识的说明: 一.OSI七层网络协议 OSI是Open System I ...

  4. OSI七层网络、TCP/IP五层网络架构、二层/三层网络

    一.OSI七层网络协议 OSI是Open System Interconnect的缩写,意为开放式系统互联. OSI参考模型各个层次的划分遵循下列原则: 1)根据不同层次的抽象分层 2)每层应当有一个 ...

  5. 计算机网络(OSI、TCP/IP、网络协议、常见网络设备工作原理)

    目录 OSI模型 TCP/IP模型 网络协议 IP协议 IP数据报格式 IP数据报分片 IPv4地址 NAT协议 ARP/RARP协议 ARP RARP DHCP协议 ICMP协议 ICMP差错报告报 ...

  6. TCP/IP通俗易懂网络协议

    昨晚在一个博主那里看懂一篇关于TCP/IP通俗易懂网络协议的文章,感觉写的非常不错,在这里就顺便做一下笔记吧.... 最简单的理解:TCP面向连接的,可靠的数据传输,建立连接需要三次握手,会造成del ...

  7. server2008网卡驱动包_从网卡发送数据再谈TCP/IP协议—网络传输速度计算-网卡构造...

    在<在深谈TCP/IP三步握手&四步挥手原理及衍生问题-长文解剖IP>里面提到 单个TCP包每次打包1448字节的数据进行发送(以太网Ethernet最大的数据帧是1518字节,以 ...

  8. TCP/IP,网络字节序与本地转换,Linux提供的转换函数htonl,htons等,sock_addr的数据结构与内容

    TCP/IP,网络字节序与本地转换,Linux提供的转换函数htonl,htons等,sock_addr的数据结构与内容 一.网络字节序存储方式: 小端存储:高位存放高地址,0x12345678的小段 ...

  9. CNT-OSI七层参考模型和TCP/IP四层网络协议

    1.计算机网络体系 计算机网络体系结构是指计算机网络层次结构模型,它是各层协议和层次之间的端口集合.在计算机网络中实现通信必须依靠网络通信协议. OSI七层参考模型:目前广泛采用的是国际标准化组织IS ...

最新文章

  1. webpack 相关文章
  2. 永洪Desktop交叉表怎么按月份汇总
  3. 深度残差网络和Highway网络
  4. python调用shell用什么类_python脚本中调用shell命令
  5. 【视觉盛宴二】长见识了,你见过BGA封装芯片的横截面吗!
  6. ad09只在一定范围内查找相似对象_dxp查找相似对象
  7. pixel和毫米怎么换算_赶紧收藏!小学阶段所有公式、单位换算、数量关系
  8. IT公司100题-14-排序数组中和为给定值的两个数字
  9. 416亿元公有云市场:阿里173亿、腾讯50亿、华为35亿
  10. 抓包教程_最简单的Wireshark抓包TCP/UDP新手5步教程(宽带故障运维必备)
  11. python的三个基本数字类型_Python基础学习--三 基本数据类型
  12. (精品)java宠物医院管理系统+论文+答辩ppt+部署视频+效果图效果视频
  13. 网络测量工具及其使用
  14. excel两列数据对比找不同_眼睛的救星,Excel怎么快速找出两列数据的不同之处?...
  15. 测试小兵成长记:磨刀不误砍柴工
  16. 关于(广义)代数特征值问题的一点注记
  17. 零基础入门学习Python视频(全42集)
  18. Echarts实现图表下钻
  19. C++的开方,平方,绝对值
  20. 软件定义网络(Software Defined Network,SDN)简介

热门文章

  1. 美国 otc 数字货币_美国数字公共图书馆的免费藏书量是第一年的三倍
  2. (29)Gulp组合任务
  3. (2)Node.js介绍
  4. HTML readonly
  5. Python笔记(6) 数字
  6. android getresponsecode -1,getHttpResponseCode()在android 2.2中返回-1
  7. wepy公共样式_wepy组件化开发之html转换组件
  8. Python入门 程序的套路
  9. POJ 3744:Scout YYF I 概率DP+特征方程+快速幂
  10. 剖析微软Hyper-V的最佳部署方式