`
schy_hqh
  • 浏览: 558368 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

(网络编程)Socket编程之TCP

 
阅读更多

网络模型
OSI参考模型
TCP/IP参考模型

网络通讯要素
1.IP地址---InetAddress
    找到对方,网络中设备的标识
    因为IP地址不易记忆,可以用主机名代替
    本地回环地址:127.0.0.1 主机名:localhost
默认IP地址

127.0.0.1 安装网卡就会有,可以ping此IP地址测试网卡

192.168.*.* 为常用的保留地址段 用在局域网中

//192.168.1.0 代表一个网络段
//192.168.1.255 代表这个网段的广播地址

2.端口号
    用于标识进程的逻辑地址,
    可以对不同进程进行标识,以便区分

    有效端口:0~65535,其中0~1024为系统使用或保留端口
       
    数据要发送到对方指定的应用程序上,
    为了表示这些应用程序,就给这些
    网络应用程序都用数据进行了标识。
    0--65535端口范围
    0--1024被系统保留
    WEB服务器    80 默认
    Tomcat服务器 8080 默认
    MySQL         3306 默认
    如果默认端口被其他应用程序占用,就会修改端口号

3.传输协议
    通信规则。也称为协议。
    国际组织定义了通用协议TCP
    另外一个常用的:UDP
    不同主机之间通信,也可以使用其他协议进行通信。
    比如:微软公司的

UDP
  将数据及源和目的三项封装成数据包,不要建立连接
  (不判断接收方是否存在,存在,则接收数据对方若不存在,则丢弃数据。是不可靠的协议)
  每个数据报的大小限制在64K内
  因无连接,是不可靠协议
  不需要建立连接,速度快
   
---速度第一,适用于数据可以适当的丢失(视频、聊天、桌面共享)
(对讲机---不知道对方是否在,也在进行数据传输)

TCP
  建立连接,形成传输数据的通道
  (需要先确定对方存在并与对方先握手,再传输数据。是可靠的协议)
  在连接中进行大数据量传输
  通过三次握手完成连接,是可靠协议
  必须建立连接,效率会稍低

握手:对方在?-->对方回复-->回复对方-----完成握手,开始建立TCP数据传输通道,传输数据。

---保证数据不丢失,适用于数据完整(下载文件)。消耗资源,速度稍慢,但可以大数据量传输。
(打电话---首先需要电话通了(对方在),才进行通讯)
   
Socket
网络编程就是Socket编程
(JSP、Servlet--JavaEE框架部分的一些组件技术)
Socket就是为网络服务提供的一种机制
通信的两端都有Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO传输


UDP传输
DatagramSocket与Datagrampacket
建立发送端,接收端
建立数据包
调用Socket的发送接收方法
关闭Socket
发送端与接收端是两个独立的运行程序

UDP的Socket服务的建立
java.net.*

DatagramSocket 
此类表示用来发送和接收数据报包的套接字
既能发送又能接收

void receive(DatagramPacket p)
从此套接字接收数据报包
void send(DatagramPacket p)
从此套接字发送数据报包

DatagramPacket
此类表示数据报包
数据报包用来实现无连接包投递服务

构造方法
DatagramPacket(byte[] buf,int length)
构造DatagramPacket,用来接收长度为length的数据包

DatagramPacket(byte[] buf,int length,InetAddress,int port)
构造数据包,用来将长度为length的包发送到指定主机的指定端口号


TCP传输
Socket和ServerSocket
建立客户端和服务端
建立连接后,通过Socket中的IO流进行数据的传输
关闭Socket
同样,客户端与服务器端是两个独立的应用程序

类Socket
此类实现客户端套接字,套接字是两台机器间通信的端点。
套接字的实际工作由SocketImpl类的实例执行
应用程序通过更改创建套接字实现的套接字工厂
可以配置它自身,以创建适合本地防火墙的套接字。

构造函数
Socekt(InetAddress address,int port)
  创建一个流套接字并将其连接到指定IP地址的指定端口号
  创建了对象就连接到服务端

Socket(String host,int port)
  创建一个流套接字并将其连接到指定主机上的指定端口号

方法:
InputStream getInputStream()
  返回此套接字的输入流

OutputStream getOutputStream()
  返回此套接字的输出流

 InetAddress getInetAddress()
  返回套接字连接的地址


类ServerSocket
构造函数:
ServerSocket(int port)
  创建绑定到特定端口的服务器套接字
 
方法:
 Socket accept()
   侦听并接收到此套接字的连接

 

 

//先打开服务端,在开客户端,否则客户端连接不到服务端。。。
//本示例:客户端向服务端发送一次数据,服务端接收到数据,并断开与客户端的连接
/*
TCP传输
1,tcp分客户端和服务端
2,客户端对应的对象是Socket
   服务端对应的对象是ServerSocet

客户端:
	查阅Socket对象,发现在
	该类对象建立时,就可以去连接指定主机
	因为tcp是面向连接的,所以在建立
	Socekt服务时,就要有服务端存在,并连接成功
	形成通路后,在该通道进行数据传输。

需求:给服务端发送一个文本数据
步骤:
1,创建Socket服务,并指定要连接的主机和端口

*/
import java.io.*;
import java.net.*;

class TcpClient
{
	public static void main(String[] args) throws Exception
	{
		//创建客户端的socekt服务,指定目的主机和端口
		Socket s = new Socket("127.0.0.1",6789);

		//为了发送数据,应该获取socket流中的输出流
		OutputStream out = s.getOutputStream();

		out.write("我来了".getBytes());

		s.close();
	}
}


/*
定义端点接收数据并打印到控制台上
服务端
1,建立服务端的socket服务,ServerSocket()并监听一个端口
2,获取连接过来的客户端对象,通过ServerSocket的accept方法
   如果没有连接就会等,所以这个方法是阻塞式的
3,客户端如果发过来数据,那么服务端要使用对应的客户端对象
	并获取到该客户端对象的读取刘来读取发过来的数据
4,关闭服务(可选--服务端常开)
*/

class  TcpServer
{
	public static void main(String[] args) throws Exception
	{
		//建立服务端的Socket服务,并监听一个端口
		ServerSocket ss = new ServerSocket(6789);
		
		//通过accept方法获取连接过来的客户端对象
		Socket s = ss.accept();

		//获取客户端发送过来的数据,使用客户端对象的读取流读取数据
		String ip = s.getInetAddress().getHostAddress();

		System.out.println(ip+"...connected");

		InputStream in = s.getInputStream();
	
		byte[] buf = new byte[1024];

		int len = in.read(buf);

		System.out.println(new String(buf,0,len));


		s.close();//关闭客户端
		//ss.close();//服务端一般都保持常开,不关闭
	}
}

 

/*
演示tcp传输的客户端和服务端的互动

需求:客户端给服务端发送数据,服务端收到数据后,给客户端反馈数据

*/

import java.io.*;
import java.net.*;

/*
客户端
1,建立socekt服务,指定要连接的主机和端口
2,获取socekt流中的输出流,将数据写到该流中
  通过网络发送给服务端
3,获取socket流中的输入流,将服务端反馈的数据获取到并打印
4,关闭客户端资源
*/

//客户端
class TcpClient2 
{
	public static void main(String[] args) throws Exception
	{
		//建立Socket连接
		Socket s = new Socket("127.0.0.1",10000);

		//向服务端发送数据
		OutputStream out = s.getOutputStream();

		out.write("服务端我来了".getBytes());
		
		//获取服务端的反馈数据
		InputStream in = s.getInputStream();

		byte[] buf = new byte[1024];

		int len = in.read(buf);//阻塞式方法,Scoket没有收到数据就等待

		System.out.println(new String(buf,0,len));

		//关闭连接
		s.close();
	}
}

//服务端
class TcpServer2 
{
	public static void main(String[] args) throws Exception
	{
		//建立服务端
		ServerSocket ss = new ServerSocket(10000);

		//侦听并接收数据
		Socket s = ss.accept();

		String ip = s.getInetAddress().getHostAddress();

		System.out.println("ip:"+ip+"...connected");

		InputStream in = s.getInputStream();

		byte[] buf = new byte[1024];

		int len = in.read(buf);//阻塞式方法,Scoket没有收到数据就等待

		System.out.println(new String(buf,0,len));

		//向客户端发送数据
		OutputStream out = s.getOutputStream();

		out.write("收到!".getBytes());

		//断开连接
		s.close();

		//ss.close();
	}
}

 

/*
需求:建立一个文本转换服务器
客户端通过键盘给服务端发送文本数据,
服务端将文本转成大写并返回给客户端
而且客户端可以不断的进行文本转换,
并输入over之后结束转换
*/
/*字符打印流
PrintWriter---非常常用。web开发时使用它将数据一行一行打到客户端
构造函数可以接收的参数类型:
1,file对象   File
2,字符串路径 String
3,字节输出流 OutputStream
4,字符输出流 Writer
*/
/*
注意:

1, PrintWriter 非常常用,应该掌握
	Printwriter 在构造时,可传入字节流,也可以传入字符流,很通用。还能传入字符串和文件流对象
	在构造时,如果传入参数true,则使用println会换行并自动刷新缓冲区
	即,可以替代缓冲区写出流的newLine()和flush()

2,该例中操作的源和目的都是文本数据,即字符数据
	为了提高效率,所以采用缓冲区字符读取和写入流
	这里要注意的是,对数据的操作使用缓冲区必须进行刷新动作
	另外,write(line)写入一行是不会写入“回车符”的
	而read(line)则要以读到“回车符”为标记,才能判断一行结束
	所以,在write的时候,就必须newLine
	接收方读的时候才会依据换行符读取成功!

3,关闭客户端时,会返回-1到socket输出流,当服务端读取到-1之后,
	应该产生相应动作来处理。
	服务端可以退出,也可以不退出!
	该怎么做呢??

*/


import java.io.*;
import java.net.*;

class  TcpClient3
{
	public static void main(String[] args) throws Exception
	{
		//建立Socket连接
		Socket s = new Socket("127.0.0.1",8888);

		//定义读取键盘数据的流对象
		BufferedReader bufr = 
			new BufferedReader(new InputStreamReader(System.in));
		
		//定义目的,将数据写入到socket输出流,发送给服务端
		//BufferedWriter bufOut = 
			//new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		
		//定义一个socket读取流,读取服务端返回的信息
		BufferedReader bufIn =
			new BufferedReader(new InputStreamReader(s.getInputStream()));

		String line = null;

		while((line=bufr.readLine())!=null)
		{			
			if(line.equals("over"))
				break;
			out.println(line);//换行并带自动刷新
			
//			bufOut.write(line);//写一行是不会写入回车符的
//			bufOut.newLine();//所以这里一定要换行
//			bufOut.flush();
			
			String serverMessage = bufIn.readLine();//读一行,要读到行结束标记才算
			System.out.println("服务端:"+serverMessage);
		}
		bufr.close();
		s.close();//关闭该流,会返回-1到该socket读取流中,导致服务端读取到之后,服务端也关闭
	}
}
class  TcpServer3 
{
	public static void main(String[] args) throws Exception
	{
		ServerSocket ss = new ServerSocket(8888);
		Socket s = ss.accept();

		String ip = s.getInetAddress().getHostAddress();
		System.out.println("客户端ip:"+ip+"...is connect");

		//读取socket读取流中的数据
		BufferedReader bufIn = 
			new BufferedReader(new InputStreamReader(s.getInputStream()));

		//目的为socket输出流。将转换后的大写数据写入到socket输出流,并发送给客户端
		//BufferedWriter bufOut = 
			//new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

		PrintWriter out = new PrintWriter(s.getOutputStream(),true);//true对println是有效自动刷新
		
		String line = null;
		while((line=bufIn.readLine())!=null)
		{
			if(line.equals("close server"))
				break;
			System.out.println("客户端message:"+line);

			out.println(line.toUpperCase());//true对println是有效自动刷新
			
//			bufOut.write(line.toUpperCase());
//			bufOut.newLine();
//			bufOut.flush();
		}
		s.close();
		ss.close();
	}
}

 

 

/*
IO 结合 Socket Tcp文件传输

需要注意的问题:
1,异常处理
2,判断文件是否存在
3,缓冲区写需要flush
4,PrintWriter的应用
5,readLine读数据到缓冲区不会读入结束标记
   另一个readLine再读缓冲区因为其中没有结束标记,所以会一直读,死循环
6,文件结束标记
	1,自定义一个结束标记。客户端与服务端协商一个读取缓冲区数据结束标记
		缺点在于:有可能读取到的文件中的数据的一行有这个标记
	2,利用时间来标记。。时间是唯一的
	3,socket提供的方法 
		void shutdownInput()  关闭输入流--在流中加入结束标记
		void shutdownOutput() 关闭输出流--在流中加入结束标记
7,发送文件之前,应该先发读取的文件名到服务端,以便服务端创建好文件
8,服务端应判断文件名是否重名,如果重名则会覆盖以前的文件,所以需要判断文件名
*/

import java.io.*;
import java.net.*;
class TextClient 
{
	public static void main(String[] args) throws Exception
	{
		//建立socket连接
		Socket s = new Socket("127.1.1.0",7777);


		//带缓冲区的字符读取流关联文件
		BufferedReader bufr = 
			new BufferedReader(new FileReader("E:/day19/SetSystemDemo.java"));
		
		//字符打印流对象包装socket字节输出流
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		
		//获取当前时间并传给服务端,以此为上传结束标记(时间是唯一的)
		long time = System.currentTimeMillis();
		
		//out.println(time+"");//long型转为字符串

		DataOutputStream dos = new DataOutputStream(s.getOutputStream());
		dos.writeLong(time);

		String line = null;
		while((line=bufr.readLine())!=null)//读取文件,文件有结束标记!当判断到结束标记是循环就结束了!
		{
			out.println(line);//结束标记是不会写入到socket字节输出流中的
		}
		
		//out.println("over");
		//s.shutdownOutput();//写入流结束标记
		
		out.println(time+"");


		//带缓冲区的字符读取流包装socket字节输入流
		BufferedReader bufIn =
			new BufferedReader(new InputStreamReader(s.getInputStream()));
		
		//服务端只返回”上传成功“一句,不用循环
		String str = bufIn.readLine();//阻塞式方法。没有数据就等待
		System.out.println(str);

		bufr.close();
		s.close();
	}
}

class TextServer 
{
	public static void main(String[] args) throws Exception
	{
		//建立服务端socket连接
		ServerSocket ss = new ServerSocket(7777);

		//侦听并接收数据
		Socket s = ss.accept();
		
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+"......连接成功");

		DataInputStream dis = new DataInputStream(s.getInputStream());
		String time = dis.readLong()+"";

		//包装socket字节输入流
		BufferedReader bufIn =
			new BufferedReader(new InputStreamReader(s.getInputStream()));

		//创建接收文件
		PrintWriter pw = new PrintWriter(new FileWriter("e:/tcp.java"),true);

		String line = null;
		while((line=bufIn.readLine())!=null)//这里读socket输入流,当中不会有文件结束标记,所以循环停不下来
		{	
			//if(line.equals("over"))		//底层一直在调用read()读取缓冲区数据!这里需要加入结束标记!
			if(line.equals(time))
				break;
			pw.println(line);
		}

		//BufferedWriter bufOut = 
			//new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		//bufOut.write("上传成功");
		//bufOut.flush();//必须刷新。

		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		out.println("上传成功!");//自动刷新
		
		s.close();
		ss.close();
	}
}

 

分享到:
评论

相关推荐

    基于TCP/IP的socket编程

    "基于TCP/IP的socket编程"是一个深入探讨如何使用socket接口进行网络通信的主题。Socket编程允许应用程序通过网络发送和接收数据,它是互联网上不同计算机之间交互的核心机制。 在给定的描述中,我们看到一个创新的...

    C# 网络编程之socket tcp 通讯demo样例

    这个"C# 网络编程之socket tcp 通讯demo样例"可能涵盖了这些基本操作,为初学者提供了理解TCP通信机制的起点。通过阅读和理解代码,你可以了解到如何在C#中建立和管理TCP连接,以及如何进行数据的收发。对于进一步的...

    socket TCP网络聊天室编程

    在IT行业中,网络编程是构建分布式系统的关键技术之一,而Socket编程则是实现网络通信的基础。本项目名为"socket TCP网络聊天室编程",其主要目标是创建一个支持多人聊天、离线消息存储以及文件传输功能的聊天平台。...

    Socket网络编程_TCP实例

    Socket网络编程是软件开发中的重要领域,特别是在分布式系统和网络通信...总之,Socket编程结合TCP协议在C#中为开发者提供了强大的网络通信能力。通过学习和实践这些实例,你可以掌握创建稳定、高效的网络应用的基础。

    VC学习笔记-基于TCP的socket编程

    在VC(Visual C++)环境下进行网络编程时,基于TCP的socket编程是实现客户端与服务器之间通信的重要方式之一。本文将从初始化、创建socket、绑定地址、监听连接、接受连接、数据传输以及关闭socket等步骤,详细介绍...

    TCP,UDP,Socket,Http网络编程面试题 47道.pdf

    本文档总结了网络编程面试题的关键知识点,涵盖了 TCP、UDP、Socket、Http 等网络协议的基础知识、网络编程的基本概念、网络协议的分层结构等内容。通过阅读本文档,读者可以了解网络编程的基本原理、网络协议的作用...

    java网络编程 socket的TCP应用编程

    - Java Socket类和ServerSocket类是进行TCP网络编程的核心API。 - ServerSocket用于创建服务器端的套接字,监听特定端口的连接请求。 - Socket用于创建客户端的套接字,与服务器建立连接。 3. **服务端编程**: ...

    TCP/IP SOCKET 网络编程

    TCP/IP SOCKET 网络编程 多模式I/O网络开发

    Socket实现tcp编程

    Socket编程是计算机网络通信中的重要概念,特别是在TCP/IP协议栈中,它提供了应用程序与网络底层通信的接口。本文将深入探讨如何使用Socket实现TCP(传输控制协议)编程,旨在帮助开发者理解和掌握网络通信的核心...

    完整版本网络编程 TCP Socket 同步、异步

    在这个主题中,TCP(传输控制协议)和Socket编程是核心概念。TCP是一种面向连接的、可靠的传输层协议,而Socket则是应用程序与TCP/IP协议族通信的接口。 **TCP协议**:TCP保证了数据的可靠传输,通过三次握手建立...

    基于TCP面向连接的 Socket网络编程实验

    2. Socket编程:Socket是一种网络编程接口,提供了基于TCP/IP协议的网络通信功能。 3. TCP三次握手:TCP三次握手是TCP协议中的一种连接建立机制,通过三次握手,客户端和服务器端可以建立可靠的连接。 4. Etheral抓...

    Python 网络编程 python网络编程 socket

    Python 网络编程_python网络编程_socket Python 网络编程是指使用 Python 语言进行网络通信编程,包括 socket 编程、网络通信协议等方面的内容。下面是对 Python 网络编程的详细介绍: 1. 网络通信的概念 网络...

    C#网络编程(socket,tcp,udp)

    C#网络编程是开发应用程序与远程系统交互的关键技术,它主要涉及了Socket、TCP和UDP等网络通信协议。本文将详细解析这些概念及其在C#中的应用。 首先,Socket是网络编程的基础,它是一个用于在网络中传输数据的端点...

    SOCKET编程之TCP服务端

    本篇将深入探讨"SOCKET编程之TCP服务端"的相关知识点,包括SOCKET的基础概念、TCP协议的特点以及如何构建一个基本的TCP服务器。 首先,让我们了解什么是SOCKET。SOCKET是操作系统提供的一个接口,它允许应用程序...

    socket网络编程 TCP传输协议实现

    在TCP Socket编程中,我们还需要注意异常处理、超时设置、数据分块与拼接、心跳检测等细节,以确保网络通信的稳定性和可靠性。同时,为了提高性能,可以考虑使用缓冲区技术、减少不必要的网络交互等优化手段。 TCP ...

    TCP/IP和UDP的socket网络编程源码和文档

    在IT领域,网络编程是构建分布式系统和网络应用的基础,其中TCP/IP协议栈和套接字(Socket)接口是核心概念。本资源包提供的是基于TCP/IP和UDP的socket网络编程源码及文档,适用于实验平台mini2440开发板和Ubuntu...

    Socket网络编程(TCP和UDP)

    Socket网络编程是计算机网络中的一种通信机制,它允许应用程序通过网络...在VS2013中使用MFC库,可以简化Socket编程过程,使得网络通信更加便捷。通过分析和实践socket_demo中的代码,你将对TCP和UDP有更深入的理解。

    iOS网络编程SocketDemo

    在iOS开发中,网络编程是不可或缺的一部分,而Socket编程则是实现网络通信的基础。Socket是一种低级别的、原始的网络通信机制,允许应用程序通过网络发送和接收数据。本示例"iOS网络编程SocketDemo"旨在帮助开发者...

Global site tag (gtag.js) - Google Analytics