• 网络编程之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. iOS 开发 右滑返回上一级控制器

    #import <objc/runtime.h> @interface UINavigationController (Transition)<UIGestureRecognizer ...

  2. Python全栈考试(一)

    1.执行 Python 脚本的两种方式 1) 使用命令行执行Python脚本: python C:\tesst.py 2) 使用各种IDE软件.pycharm wing 2.简述位.字节的关系 位 ( ...

  3. JavaScript细节成败

    1.var 众所周知var用来定义变量 如 undefined,number,string,bool,array,function,object,null. 但有时候为了省事,就会出现一些内存泄露的情 ...

  4. Flask框架

    FLask框架的简单介绍 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请 ...

  5. python对pywifi模块的认识

    pywifi是一个用来搞wifi的模块 下一章我们将用他破解wifi密码 pywifi安装 pip install pywifi 下列代码判断是否有无限网卡 import pywifi import ...

  6. [51nod1474]宝藏图

    有n堆宝藏,每一堆宝藏有一个挖掘所需要的时间ti,有一个价值qi. 现在是做一个宝藏图.这个宝藏图是这样的,宝藏图的形状是一棵二叉树,二叉树刚好有k个叶子结点,从n堆宝藏中选k堆放到二叉树的叶子结点上 ...

  7. Codeforces Round #416 (Div. 2)(A,思维题,暴力,B,思维题,暴力)

    A. Vladik and Courtesy time limit per test:2 seconds memory limit per test:256 megabytes input:stand ...

  8. Codeforces Round #331 (Div. 2) _A. Wilbur and Swimming Pool

    A. Wilbur and Swimming Pool time limit per test 1 second memory limit per test 256 megabytes input s ...

  9. Spark环境搭建(下)——Spark安装

    1. 下载Spark 1.1 官网下载Spark http://spark.apache.org/downloads.html 打开上述链接,进入到下图,点击红框下载Spark-2.2.0-bin-h ...

  10. Oracle_insert_delete_update

    Oracle_insert_delete_update --复制表格的结构 create table temp as (select * from emp where 1=2); select * f ...