黑马程序员---网络编程技术

--------- android培训java培训、期待与您交流! ----------

 

黑马程序员---网络编程技术

 

网络通讯的方式主要有两种:

1、 TCP(传输控制协议)方式

2、 UDP(用户数据报协议)方式

为 了方便理解这两种方式,还是先来看一个例子。大家使用手机时,向别人传递信息时有两种方式:拨打电话和发送短信。使用拨打电话的方式可以保证将信息传递给 别人,因为别人接听电话时本身就确认接收到了该信息。而发送短信的方式价格低廉,使用方便,但是接收人有可能接收不到。

在网络通讯中,TCP方式就类似于拨打电话,使用该种方式进行网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。而UDP方式就类似于发送短信,使用这种方式进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得。

这两种传输方式都是实际的网络编程中进行使用,重要的数据一般使用TCP方式进行数据传输,而大量的非核心数据则都通过UDP方式进行传递,在一些程序中甚至结合使用这两种方式进行数据的传递。

由于TCP需要建立专用的虚拟连接以及确认传输是否正确,所以使用TCP方式的速度稍微慢一些,而且传输时产生的数据量要比UDP稍微大一些。 


OSI参考模型的全称是开放系统互连参考模型,它是由国际化标准组织ISO提出的一个网络系统互连模型。ISO组织把网络通讯工作分为7层,一到四层被认为是低层, 这些层与数据移动密切相关,5到7层是高层,包含应用程序级的数据,每一层负责一项具体的工作,然后把数据交给下一层。

InetAddress:

用于描述IP的类,主要方法有:
String  getHostAddress();:返回对象IP地址的字符串形式

String  getHostName(); :返回对象的主机名

static   InetAddress  getLocalHost():获取本地主机对象

static   InetAddress  getByName("IP地址"):获取IP地址或者域名获取主机对象。

static  InetAddress[]  getAllByAddress("域名"):通过主机名或者域名获取不同IP地址的主机对象数组。

注:如果IP地址和对应的主机名这个映射关系没有在网络上,其他主机通过IP地址去搜索到了,但是会有没解释成功的情况,getHostName()获取的还是IP的地址;getHostName();会有一个解释过程。

       当输入域名用getByName方法获取主机对象时,IP地址并不是唯一的。因为网络上的服务器可能有多台,对应不用的IP地址,这时就要用:getAllByAddress方法。大部分用getAllByAddress方法为主,因为getHostName方法需要解释。

 

UDP、TCP和Socket

UDP: 1.将数据及源和谜底封装在数据包中,不需要建立连接

       2.每个数据的大小控制在64k内

       3.因无连接,是不可靠协议

       4.不需要建立连接,速度快

 


TCP: 1. 需要建立连接,形成传输数据的通道

       2.在连接中进行大量数据传输

       3.通过三次握手完成连接,是可靠协议

       4.必须要建立连接,效率稍低

 

Socket 套接字:1. Socket 是为网络服务提供的一种机制

              2. 通信的两端都要具有Socket

              3. 网络通信其实就是Socket 间的通信

              4.数据在两个Socket 间通过IO传输

个人理解可以将Socket 理解成码头,A城市的码头将货物运到B码头通过河流运输,A城市电脑A,B城市电脑B,码头:Socket ,货物就是数据,河流就是IO流

 
UDP传输:

1、定义UDPSocket服务,通常会监听一个端口,其实就是给这个接收网络应用程序定义数字标识。方便于明确哪些数据传输过来后是该应用程序可以处理的。

2、定义一个空的数据包,用于存储接收到的字节数据。因为数据包对象中有更多的功能可以崎岖字节数据中的同数据信息。

3通过Socket服务的receive方法接收到的数据存入已定义好的数据包中。

4、通过数据包对象的特有功能,将这些不同的数据取出。

5、关闭资源。

注意:不手动定义端口的话,虚拟机会自动添加一个端口,但是就会和发送端定义的端口对应不上,就接收不到数据。另外,DatagramPacket中的getPort()是获取发送端的自身的端口,而不是发送端的目的端口。

	public static void main(String[] args)  throws Exception
	{
		DatagramSocket ds = new DatagramSocket(11111);
		byte[] buf = new byte[1024];
		DatagramPacket dp = new DatagramPacket(buf,buf.length);
		String str = null;
		while(true)
		{
			ds.receive(dp);
			str = new String(buf,0,dp.getLength());
			String ip = dp.getAddress().getHostAddress();
			System.out.println(ip+"::"+str);
		}
	}

 

TCP传输:

建立客户端和服务端,建立连接后,通过socket的IO流进行数据传输。

 

对客户端和服务端的理解:

客户端:

                  该对象建立时,就可以去连接指定主机,因为TCP是面向连接的,所以在建立Socket服务时,只要有服务在并连接成功形成通路后,该通道进行数据的传输


服务端:

                  1. 建立服务端的Socket服务,ServerSocket(), 并监听一个端口

                  2. 获取连接过来的客户端对象,通过ServerSocket的accept方法,没有连接就会等,所以这个方法是阻塞式的。

                  3.如果客户端发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发来的数据

                  4.关闭服务器

 

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

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

*/

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

*/
import java.io.*;
import java.net.*;
class myServer2
{
	public static void main(String[] args)  throws Exception
	{
		//建立服务端
		ServerSocket server = new ServerSocket(10022);
		
		while(true)
		{
			//获取客户端对象
			Socket s = server.accept();
			String ip = s.getInetAddress().getHostAddress(); 
			System.out.println(ip+"...连接服务器!");
			//客户端对象输出流和读取流
			//BufferedWriter bfos = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
			BufferedReader bfis = new BufferedReader(new InputStreamReader(s.getInputStream()));

			//简化代码不用BufferedWriter和转换流,用PrintWriter;
			PrintWriter pw = new PrintWriter(s.getOutputStream(),true);


			//循环获取客户端信息和进行反馈
			while(true)
			{
				String line = bfis.readLine();//当客户端关闭,这里就会返回-1
				if("over".equals(line))
					break;
				System.out.println(ip+"::"+line);
				pw.println(line.toUpperCase());
				
				/*
				bfos.write(line.toUpperCase());
				//跟客户端一样,要加上,不然客户端那里也是等待
				bfos.newLine();
				bfos.flush();
				
				*/
			}
			System.out.println(ip+"...以结束连接!");
			s.close();
		}
	}

}

class  myTcpDemo2
{
	public static void main(String[] args) throws Exception
	{
		//客户端连接
		Socket sock = new Socket("192.168.2.100",10022);
		//获取键盘录入
		BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));
		//客户端输出流和读取流
		//BufferedWriter bfos = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));
		BufferedReader bfis = new BufferedReader(new InputStreamReader(sock.getInputStream()));

		//简化代码不用BufferedWriter和转换流,用PrintWriter;
		PrintWriter pw = new PrintWriter(sock.getOutputStream(),true);

		String line = null;
		while((line=bfr.readLine())!=null)
		{
			if("over".equals(line))
			{
				pw.println(line);
				/*
				bfos.write(line);
				bfos.flush();*/
				break;
			}
			pw.println(line);
			/*
			bfos.write(line);
			//这里要加上newLine方法,不然服务端那里的readLine方法没有读取到换行,就会一直等待
			bfos.newLine();
			bfos.flush();
			*/
			String str = bfis.readLine();
			System.out.println("Server::"+str);
		}
		bfr.close();
		sock.close();	
	}
}


 

--------- android培训java培训、期待与您交流! ----------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
黑马程序员是一家IT培训机构,提供各种技术培训课程,包括网络通信相关的课程。在网络通信中,socket是一种编程接口,用于实现不同主机之间的通信。通过socket函数创建一个套接字,指定域名、类型和协议。域名可以是AF_INET、AF_INET6或AF_UNIX,类型可以是SOCK_STREAM(用于TCP通信)或SOCK_DGRAM(用于UDP通信),协议可以是0表示自动选择适合的协议。创建成功后,套接字会返回一个文件描述符,用于在后续的通信中进行读写操作。 在TCP通信中,服务器和客户端的流程大致相同。服务器首先使用socket函数创建套接字,然后使用bind函数绑定服务器地址结构,接着使用listen函数设置监听上限。服务器通过accept函数阻塞监听客户端连接,并使用read函数读取客户端传来的数据,进行相应的处理后,使用write函数将处理后的数据写回给客户端,最后使用close函数关闭套接字。客户端也是先使用socket函数创建套接字,然后使用connect函数与服务器建立连接,之后使用write函数将数据写入套接字,再使用read函数读取服务器返回的数据,最后使用close函数关闭套接字。 在UDP通信中,服务器和客户端的流程也有所不同。服务器使用socket函数创建套接字,指定类型为SOCK_DGRAM,然后使用bind函数绑定服务器地址结构。服务器通过recvfrom函数接收客户端传来的数据,并进行相应的处理,最后使用sendto函数将处理后的数据发送回给客户端。客户端同样使用socket函数创建套接字,然后通过sendto函数将数据发送给服务器,再使用recvfrom函数接收服务器返回的数据。 总之,socket网络通信是通过创建套接字实现不同主机之间的通信。根据使用的协议不同,可以选择TCP或UDP通信方式。服务器和客户端根据流程进行相应的操作,实现数据的传输和交互。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值