TCP编程

TCP编程是面向连接的数据传输,所以需要时用IO流来建立连接。

用户输出流到服务器,服务器输入流接收数据。

服务器输出流到用户,用户输入流接收。

基本流程

服务器端

  • 创建服务器端:ServerScoekt 对象
  • 阻塞时监听用户接入:accep() 返回Socket对象
  • 建立连接:与返回的Socket对象建立IO流,getInputStream()方法与getOutputStream方法
  • 处理数据
  • 关闭流,关闭Socket对象,关闭服务器(一般不关服务器)

用户端

  • 创建Socket对象:Socket(targetHost,targetPort)
  • 建立连接:创建输出流
  • 传输数据:输入流写
  • 关闭流
  • 关闭Socket对象

基础版本示例

服务器端

package _20191218;

import java.io.DataInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; /**
* 通过tcp传输数据的服务端,实现的是服务器端
* @author TEDU
*
*/
public class TCPServer {
public static void main(String[] args) throws IOException {
System.out.println("-----server------");
//建立服务器
ServerSocket server = new ServerSocket(6677);
//阻塞式接收Socket
Socket client = server.accept();
//建立连接
DataInputStream dis = new DataInputStream(client.getInputStream());//选择需要的合适的流,不需要如本文的流
//接收数据并处理
Object obj1 = dis.readUTF();
Object obj2 = dis.readInt();
Object obj3 = dis.readFloat();
System.out.println(obj1);
System.out.println(obj2);
System.out.println(obj3);
//关闭流及服务器
dis.close();
client.close();
//server.close()//服务器无需关闭
}
}

  

用户端

package _20191218;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException; public class TCPClient {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("-----client------");
//新建客户端Socket
Socket client = new Socket("localhost",6677);
//建立连接
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
//发送数据
String str = "fuck";
dos.writeUTF(str);
dos.writeInt(89);
dos.writeFloat(213.4f);
//关闭流和连接
dos.close();
client.close();
}
}

  

测试结果

模拟登陆服务器

客户端与服务器端都可以想对方发送消息。但服务器方是被动响应消息。

服务器端

package _20191218;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; /**
* 服务器有响应功能,对于用户的请求进行处理,如账号密码均正确,回应登录成功,否则回应登录失败
* @author TEDU
*
*/
public class TCPLoginServer {
public static void main(String[] args) throws IOException {
System.out.println("服务器端开启");
//创建服务器端
ServerSocket server = new ServerSocket(6677);//端口号不能忘
//阻塞式监听请求:Socket accept()
Socket client = server.accept();
//建立连接
DataInputStream dis = new DataInputStream(client.getInputStream());
//读取数据
String str = dis.readUTF();
String[] datas = str.split("&");
int count = 0;
//输出IO流
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
for(String data : datas) {
if(data.equals("zhanghao")) {
count++;
}
if(data.equals("mima")){
count++;
}
}
if(count == 2) {
dos.writeUTF("登陆成功");
}else {
dos.writeUTF("登录失败");
}
//关闭流、关闭服务器(如果有必要的话)
dos.close();
dis.close();
//server.close();//关闭服务器,如果必要的话
}
}

  

客户端

package _20191218;

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner; /**
* 客户端请求,输入账号密码试图登录服务器
* @author TEDU
*
*/
public class TCPLoginClient {
public static void main(String[] args) throws UnknownHostException, IOException {
System.out.println("用户端开启");
//创建用户端
Socket client = new Socket("localhost",6677);
System.out.println(client);
//建立连接
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
//用户输入账号密码
Scanner scan = new Scanner(System.in);
System.out.println("请输入账号:");
String account = scan.nextLine();
System.out.println("请输入密码:");
String password = scan.nextLine();
//传输数据
dos.writeUTF(account+"&"+password);
// bw.write(password);
dos.flush();
//等待响应
DataInputStream dis = new DataInputStream(client.getInputStream());
System.out.println(dis.readUTF());
//关闭连接(如果需要的话)
dis.close();
dos.close();
client.close();
}
}

  

测试结果

文件传输至服务器

客户端将文件传输至服务器端。

客户端

package _20191218;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket; /**
* 从客户端传动文件到服务器端
* @author TEDU
*
*/
public class FileTCPClient {
public static void main(String[] args) throws IOException {
//创建客户端
Socket client = new Socket("localhost",6687);
//与本地文件建立连接 IO流
InputStream is = new FileInputStream(new File("GIF.gif"));
//与客户端建立连接 IO流
OutputStream os = new BufferedOutputStream(client.getOutputStream());
//读取并发送文件
byte[] datas = new byte[1024*10];
int len;
while((len = is.read(datas))!=-1) {//读取文件
os.write(datas,0,len);//发送文件
}
os.flush();
//关闭流及端
os.close();
is.close();
client.close();
}
}

  

服务器端

package _20191218;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; /**
* 接收并存储从客户端传过来的文件
* @author TEDU
*
*/
public class FileTCPServer {
public static void main(String[] args) throws IOException {
//建立服务器端
ServerSocket server = new ServerSocket(6687);
//阻塞式接收Socket
Socket client = server.accept();
//与客户端建立连接
InputStream is = new BufferedInputStream(client.getInputStream());
//与本地文件建立连接(如文件为空则新建)
OutputStream os = new FileOutputStream(new File("copy.gif"));
//读取数据
byte[] datas = new byte[1024*10];
int len;
while((len = is.read(datas))!=-1) {
//处理数据:写入文件
os.write(datas,0,len);
}
os.flush();
//关闭流与连接
os.close();
is.close();
server.close();
}
}

  

先运行服务器端,再运行客户端即可复制完成。

模拟多人登录服务器:服务器多线程

运行一个服务器端,运行多个用户端尝试登录。多开几个控制台。

服务器端

package _20191218;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; /**
* 支持多用户登录的服务器
* @author TEDU
*/
public class TCPMultipleLoginServer{
public static void main(String[] args) {
System.out.println("服务器开启");
//新建服务器端
ServerSocket server = null;
try {
server = new ServerSocket(6788);
} catch (IOException e) {
e.printStackTrace();
}
//声明客户端套机字
Socket client = null;
//循环运行请求服务器
while(true) {
//客户端套接字
try {
client = server.accept();//阻塞接受请求
System.out.println("有用户尝试登录");
} catch (IOException e) {
e.printStackTrace();
}
//线程开始(接受客户端发来的数据,做出回应)
new Thread(new Channel(client)).start();
} }
//写一个内部类,用来实现Runnable接口
static class Channel implements Runnable{
//输入流与输出流
DataInputStream dis;
DataOutputStream dos;
//构造方法:传入已经创建好的client
public Channel(Socket client) {
//建立连接
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
try {
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
//接受数据
String[] datas = Receive();
//响应
if(datas[0].equals("zhanghao")&&datas[1].equals("mima")) {
send("登陆成功");
}else {
send("登录失败");
}
//关闭
release();
}
//接受请求数据
public String[] Receive() {
try {
String[] datas = dis.readUTF().split("&");
return datas;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//响应
public void send(String response) {
try {
dos.writeUTF(response);
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭
public void release() {
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

  

用户端

  

package _20191218;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner; /**
* TCP多用户登录服务器
*/
public class TCPMultipleLoginClient{
public static void main(String[] args) {
//创建客户端套接字
Socket client = null;
try {
client = new Socket("localhost",6788);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
new Send(client).send();
new Receive(client).receive();
}
//创建传输数据类
static class Send{
//输出流
DataOutputStream dos;
//构造方法:传入client
public Send(Socket client) {
try {
dos = new DataOutputStream(client.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
//传输数据到服务器的方法
public void send() {
Scanner scan = new Scanner(System.in);
System.out.println("请输入账号:");
String account = scan.nextLine();
System.out.println("请输入密码:");
String password = scan.nextLine();
try {
dos.writeUTF(account+"&"+password);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//创建接收数据类
static class Receive{
//输入流
DataInputStream dis;
public Receive(Socket client) {
try {
dis = new DataInputStream(client.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
//接收方法
public void receive() {
try {
String message = dis.readUTF();
System.out.println(message);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

  

63 网络编程(四)——TCP编程的更多相关文章

  1. 网络编程之TCP编程

    网络编程之TCP编程 前面已经介绍过关于TCP协议的东西,这里不做赘述.Java对于基于TCP协议的网络通信提供了良好的封装,Java使用socket对象来代表两端的通信窗口,并通过Socket产生I ...

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

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

  3. python网络-Socket之TCP编程(26)

    一.TCP简介 1.TCP介绍 TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的.可靠的.基于字节流的传输层通信协议. TC ...

  4. linux高性能服务器编程 (四) --TCP/IP通信案例

    第四章 TCP/IP通信案例 HTTP代理服务器的大致工作原理        在HTTP通信链上,客户端和服务器之间通常存在某些中转代理服务器.它们提供对目标资源的中转访问.一个HTTP请求可能被多个 ...

  5. Linux网络编程系列-TCP编程实例

    实例: client #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #inc ...

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

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

  7. 牛客网Java刷题知识点之TCP、UDP、TCP和UDP的区别、socket、TCP编程的客户端一般步骤、TCP编程的服务器端一般步骤、UDP编程的客户端一般步骤、UDP编程的服务器端一般步骤

    福利 => 每天都推送 欢迎大家,关注微信扫码并加入我的4个微信公众号:   大数据躺过的坑      Java从入门到架构师      人工智能躺过的坑         Java全栈大联盟   ...

  8. 【网络编程1】网络编程基础-TCP、UDP编程

    网络基础知识 网络模型知识 OSI七层模型:(Open Systems Interconnection Reference Model)开放式通信系统互联参考模型,是国际标准化组织(ISO)提出的一个 ...

  9. 网络编程协议(TCP和UDP协议,黏包问题)以及socketserver模块

    网络编程协议 1.osi七层模型 应用层  表示层  会话层  传输层  网络层  数据链路层  物理层 2.套接字 socket 有两类,一种基于文件类型,一种基于网络类型 3.Tcp和udp协议 ...

随机推荐

  1. Object.assign的使用

    语法: Object.assign(target, ...sources)//target目标对象,sources源对象,返回值目标对象 使用说明: 如果目标对象中的属性具有相同的键,则属性将被源对象 ...

  2. SQL Server Compact 3.5环境部署<转>

    通过使用 Microsoft Visual Studio 开发环境,可以开发使用 SQL Server Compact 3.5 的应用程序.Visual Studio 是开发和部署使用 SQL Ser ...

  3. webview学习

    Android中WebView使用6,js调java实现播放视频 https://blog.csdn.net/zhaihaohao1/article/details/77993890 android ...

  4. Ubuntu18.04安装cudnn7.6.1

    注:如果使用anaconda,貌似不需要安装cuda和cudnn,安装tensorflow时会自动安装 1.进入nvidia官网https://developer.nvidia.com/cudnn下载 ...

  5. Nginx七层负载均衡的几种调度算法

      Nginx是一款轻量级的高性能web服务器,同时也是一款非常优秀的负载均衡器和反向代理服务器.由于支持强大的正则匹配规则.动静分离.URLrewrite功能及安装配置简单且对网络稳定性依赖非常小等 ...

  6. 关于交叉熵损失函数Cross Entropy Loss

    1.说在前面 最近在学习object detection的论文,又遇到交叉熵.高斯混合模型等之类的知识,发现自己没有搞明白这些概念,也从来没有认真总结归纳过,所以觉得自己应该沉下心,对以前的知识做一个 ...

  7. 单文件WebUploader做大文件的分块和断点续传

    前言: WebUploader是由Baidu WebFE(FEX)团队开发的一个简单的以HTML5为主,FLASH为辅的现代文件上传组件.在现代的浏览器里面能充分发挥HTML5的优势,同时又不摒弃主流 ...

  8. 201671030129 周婷 实验十四 团队项目评审&课程学习总结

    项目 内容 这个作业属于哪个课程 软件工程 这个作业的要求在哪里 团队项目评审&课程学习总结 课程学习目标 (1)完成项目验收(2)反思总结课程学习内容 1.对<实验一 软件工程准备&g ...

  9. NOIP 2006 明明的随机数

    洛谷 P1059 明明的随机数 洛谷传送门 JDOJ 1423: [NOIP2006]明明的随机数 T1 JDOJ传送门 Description 明明想在学校中请一些同学一起做一项问卷调查,为了实验的 ...

  10. mysql数据库锁的机制-one

    锁概念 : 当高并发访问同一个资源时,可能会导致数据不一致,需要一种机制将用户访问数据的顺序进行规范化,以保证数据库数据的一致性.锁就是其中的一种机制. 举例 :以买火车票为例,火车票可面向广大消费者 ...