• 网络编程之TCP编程

前面已经介绍过关于TCP协议的东西,这里不做赘述。Java对于基于TCP协议的网络通信提供了良好的封装,Java使用socket对象来代表两端的通信窗口,并通过Socket产生IO流来进行网络通信。说白了,玩基于Socket的网络编程无非就是使用ServerSocket创建一个服务器,然后使用socket进行通信,如果复杂一点呢,在加入多线程操作,用NIO代替IO来实现非阻塞Socket通信。



在很久以前我就听过一个前辈讲过,他说这个Socket翻译的很是别扭,叫做什么套接字,具体的不管了,反正他就叫这名字。那么关于这个套接字,要如何理解呢?一个Socket相当于一个电话机。OutputStream(输出)相当于话筒,InputStream(输入)相当于听筒。



服务器端要创建的对象:java.Net.ServerSocket。那么如何创建一个TCP服务器端程序呢?

       1). 创建一个ServerSocket

       2). 从ServerSocket接受客户连接请求

       3). 创建一个服务线程处理新的连接

       4). 在服务线程中,从socket中获得I/O流

       5). 对I/O流进行读写操作,完成与客户的交互

       6). 关闭I/O流

       7). 关闭Socket

客户端要创建的对象:java.Net.Socket。那么如何创建一个TCP客户端程序呢?

      1). 创建Socket

      2). 获得I/O流

      3). 对I/O流进行读写操作

      4). 关闭I/O流

      5). 关闭Socket





      以下代码实现了一个服务器端和一个客户端:

import java.net.*;
import java.io.*; public class Server
{
public static void main(String[] args) throws IOException
{
// 创建一个ServerSocket,用于监听客户端Socket的连接请求
ServerSocket ss = new ServerSocket(30000);
// 采用循环不断接受来自客户端的请求
while (true)
{
// 每当接受到客户端Socket的请求,服务器端也对应产生一个Socket
Socket s = ss.accept();
// 将Socket对应的输出流包装成PrintStream
PrintStream ps = new PrintStream(s.getOutputStream());
// 进行普通IO操作
ps.println("您好,您收到了服务器的新年祝福!");
// 关闭输出流,关闭Socket
ps.close();
s.close();
}
}
}
import java.net.*;
import java.io.*; public class Client
{
public static void main(String[] args) throws IOException
{
Socket socket = new Socket("127.0.0.1", 30000);
// 将Socket对应的输入流包装成BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 进行普通IO操作
String line = br.readLine();
System.out.println("来自服务器的数据:" + line);
// 关闭输入流、socket
br.close();
socket.close();
}
}



上面的代码比较简单,当然我们可以加入多线程,这样子更加符合实际应用,因为前面的单线程很容易在IO流做读取操作的时候发生阻塞。下面的代码,服务器为每个socket单独启动一个线程,每条线程负责和一个客户端进行通信,客户端同样单独启动一个线程,该线程专门负责读取服务器数据。具体代码如下:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList; public class MyServer
{
//定义保存所有Socket的ArrayList
public static ArrayList<Socket> socketList = new ArrayList<Socket>(); public static void main(String[] args) throws IOException
{
ServerSocket ss = new ServerSocket(30000);
while (true)
{
// 此行代码会阻塞,将一直等待别人的连接
Socket s = ss.accept();
socketList.add(s);
// 每当客户端连接后启动一条ServerThread线程为该客户端服务
new Thread(new ServerThread(s)).start();
}
}
} class ServerThread implements Runnable
{
// 定义当前线程所处理的Socket
Socket s = null;
// 该线程所处理的Socket所对应的输入流
BufferedReader br = null; public ServerThread(Socket s) throws IOException
{
this.s = s;
// 初始化该Socket对应的输入流
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
} public void run()
{
try
{
String content = null;
// 采用循环不断从Socket中读取客户端发送过来的数据
while ((content = readFromClient()) != null)
{
// 遍历socketList中的每个Socket,
// 将读到的内容向每个Socket发送一次
for (Socket s : MyServer.socketList)
{
PrintStream ps = new PrintStream(s.getOutputStream());
System.out.println("这里是服务器。。。");
System.out.println(content);
ps.println(content);
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
} // 定义读取客户端数据的方法
private String readFromClient()
{
String str = null;
try
{
str = br.readLine();
}
// 如果捕捉到异常,表明该Socket对应的客户端已经关闭
catch (Exception e)
{
// 删除该Socket。
MyServer.socketList.remove(s);
}
return str;
}
}
import java.io.*;
import java.net.*; public class MyClient
{
public static void main(String[] args) throws Exception
{
Socket s = new Socket("127.0.0.1", 30000);
// 客户端启动ClientThread线程不断读取来自服务器的数据
new Thread(new ClientThread(s)).start();
// 获取该Socket对应的输出流
PrintStream ps = new PrintStream(s.getOutputStream());
String line = null;
// 不断读取键盘输入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while ((line = br.readLine()) != null)
{
// 将用户的键盘输入内容写入Socket对应的输出流
ps.println(line);
}
}
} class ClientThread implements Runnable
{
// 该线程负责处理的Socket
private Socket s;
// 该线程所处理的Socket所对应的输入流
BufferedReader br = null; public ClientThread(Socket s) throws IOException
{
this.s = s;
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
} public void run()
{
try
{
String content = null;
// 不断读取Socket输入流中的内容,并将这些内容打印输出
while ((content = br.readLine()) != null)
{
System.out.println("这里是客户端。。。");
System.out.println(content);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

网络编程之TCP编程的更多相关文章

  1. [Python] 网络编程之TCP编程

    转自:TCP编程 - 廖雪峰的官方网站 Socket是网络编程的一个抽象概念.通常我们用一个Socket表示“打开了一个网络链接”,而打开一个Socket需要知道目标计算机的IP地址和端口号,再指定协 ...

  2. 网络编程之UDP编程

    网络编程之UDP编程 UDP协议是一种不可靠的网络协议,它在通信的2端各建立一个Socket,但是这个Socket之间并没有虚拟链路,这2个Socket只是发送和接受数据的对象,Java提供了Data ...

  3. Java网络编程之TCP、UDP

    Java网络编程之TCP.UDP 2014-11-25 15:23 513人阅读 评论(0) 收藏 举报 分类: java基础及多线程(28) 版权声明:本文为博主原创文章,未经博主允许不得转载.   ...

  4. Python网络编程之TCP套接字简单用法示例

    Python网络编程之TCP套接字简单用法示例 本文实例讲述了Python网络编程之TCP套接字简单用法.分享给大家供大家参考,具体如下: 上学期学的计算机网络,因为之前还未学习python,而jav ...

  5. java网络编程之TCP通讯

    java中的网络编程之TCP协议的详细介绍,以及如何使用,同时我在下面举2例说明如何搭配IO流进行操作, /* *TCP *建立连接,形成传输数据的通道: *在连接中进行大数据量传输: *通过三次握手 ...

  6. 网络编程之TCP/IP各层详解

    网络编程之TCP/IP各层详解 我们将应用层,表示层,会话层并作应用层,从TCP/IP五层协议的角度来阐述每层的由来与功能,搞清楚了每层的主要协议,就理解了整个物联网通信的原理. 首先,用户感知到的只 ...

  7. Java网络编程之TCP

    Java网络编程之TCP ​ TCP主要需要两个类:Socket和ServerSocket,Socket是客户端连接服务器时创建,参数需要指定服务器的ip和端口,ServerSocket是服务器端创建 ...

  8. C#网络程序设计(3)网络传输编程之TCP编程

        网络传输编程指基于各种网络协议进行编程,包括TCP编程,UDP编程,P2P编程.本节介绍TCP编程.     (1)TCP简介: TCP是TCP/IP体系中最重要的传输层协议,它提供全双工和可 ...

  9. 网络编程之TCP

    知识补充:源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字.其用于标识客户端请求的服务器和服务. TCP编程的实现步骤:服务器端:1.通过ServletSocket创建绑定到指定客户端 ...

随机推荐

  1. 什么是BIG?如何买BIG?

    谈到BIG,就要谈到BIG ONE.BigONE号称"全民交易所",也称"云币国际站".是 INBlockchian(硬币资本)旗下全球区块链资产现货交易所,是 ...

  2. Kafka的特点及使用场景

    Kafka是分布式发布-订阅消息系统.它最初由LinkedIn公司开发,之后成为Apache项目的一部分.Kafka是一个分布式的,可划分的,冗余备份的持久性的日志服务.它主要用于处理活跃的流式数据. ...

  3. 入门干货之Electron的.NET实现-Electron.NET

    0x01.Electron.NET 1.介绍 Electron是由Github上的一支团队和一群活跃贡献者维护.用HTML,CSS和JavaScript来构建跨平台桌面应用程序的一个开源库. Elec ...

  4. Mixin Network Whitepaper

    [译] Mixin Network(网络) 看到了李笑来老师牵头的 Mixin, 也仔细查看了 Mixin 白皮书 ,决定翻译过来 构造一个最大的,并且对开发者友好的移动区块链网络,连接现有的所有区块 ...

  5. C语言范例学习06-上

    第六章 文件操作 前言:第五章是C语言在数学上的一些应用,我觉得没有必要,便跳过了.这章正如我标题所写的,是C语言在文件上的操作.学习了这个后,你们可以自行编辑一些所需的快捷程序,来实现一些既定的目的 ...

  6. 五分钟学习React(三):纯HTML代码搭建React应用

    上一期我们使用了React官方的脚手架运行React应用.大家可能会觉得这种方法很繁琐,需要配置各种第三方插件.JQuery时代的前端真是让人怀念.这一期,我就带领大家创建一个"怀旧版&qu ...

  7. IdentityServer(14)- 使用EntityFramework Core配置和操作数据

    IdentityServer具有良好的扩展性,其中一个可扩展点是用于IdentityServer所需数据的存储机制. 本快速入门介绍了如何配置IdentityServer以使用EntityFramew ...

  8. virtio 简介

    我的微信公众号 aCloudDeveloper 专注于云计算技术,互联网技术,生活感悟,打造干货分享平台,每周至少一更,欢迎小伙伴们多多关注! 什么是 virtio virtio 是一种 I/O 半虚 ...

  9. java字符串比较

    我最近刚学java,今天编程的时候就遇到一个棘手的问题,就是关于判断两个字符串是否相等的问题.在编程中,通常比较两个字符串是否相同的表达式是"==",但在java中不能这么写.在j ...

  10. jQuery实现跨域请求实例

    首先准备两个项目做测试(jsonp1,jsonp2) 一:在jsonp1中做一个用于测试的链接 def ajax(request): callbacks = request.GET.get(" ...