网络编程.docx
- 文档编号:6026365
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:24
- 大小:23.44KB
网络编程.docx
《网络编程.docx》由会员分享,可在线阅读,更多相关《网络编程.docx(24页珍藏版)》请在冰豆网上搜索。
网络编程
网络编程
网络编程基础
IP:
当我们一台机器将信息发送到另一台机器,要先找到对方的IP,IP是计算机的地址。
端口:
,然后将数据发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识。
为了方便称呼这个数字,就叫做端口,逻辑端口
协议:
它是一种通信规则,国际组织定义了通用协议TCP/IP.
IP编程
IPInternetProtocol(网络之间互连的协议)的缩写,IP地址在java中也有自己的类,这个类在包下是一个InetAddress类,这个类是一个无构造函数的一个类。
这个类常用的方法:
a)staticInetAddressgetLocalHost():
返回本地主机。
获取引用对象
b)StringgetHostName():
获取此IP地址的主机名。
c)StringgetHostAddress():
回IP地址字符串(以文本表现形式)。
//常用
d)staticInetAddressgetByName(Stringhost):
在给定主机名的情况下确定主机的IP地址。
获取引用对象
e)StringtoString():
将此IP地址转换为String
UDP和TCP特点
UDP特点
a)面向无连接,即将数据及源和目的封装成数据包,不需要建立连接
b)数据包限制,即每个数据包的大小限制在64k。
c)不可靠协议,因为无连接,是不可靠协议
d)速度快,因为不需要建立连接,速度很快,但容易丢包
TCP特点:
a)面向连接,建立连接,形成传输数据的同道
b)大数据传输,在连接中进行大数据传输,不用封装包
c)可靠协议,通过三次握手完成连接
d)效率较低,必须建立连接,效率会稍低
UDP网络编程
UDP发送端
Socket是一种现实中的插槽或者插座的意思,为网络服务提供的一种机制
当我们发送一段信息时,UDP的发送过程:
1.建立UDPSocket服务。
使用的是DatagramSocket对象
2.提供数据,并将数据封装到数据包中
a)数据:
是一个byte[]数组存放的内容
b)数据包,使用的是DatagramPacket对象,
构造方法是DatagramPacket(byte[]byf,intlength,InetArreessaddress,intport)
即(数据,数据的长度,要发送的主机(主机或IP),端口号)
3.通过Socket服务的发送功能,将数据包发出去
DatagramSocket的send(数据包对象)方法
4.关闭资源
我们再用代码来演示下具体过程:
import.*;
classUPDSend
{
publicstaticvoidmain(String[]args)throwsException
{
//过程1:
创建一个UDP服务,通过DatagramSocket对象
DatagramSocketds=newDatagramSocket();
//过程2-1:
创建一组数据
byte[]buf="Helloworldwelcome".getBytes();
//过程2-2:
创建数据包,将数据封装到数据包里,通过DatagramPacket对象
DatagramPacketdp=
newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.100"),8080);
//过程3:
发送数据,使用DatagramSocket的send()方法。
ds.send(dp);
}
}
UDP接受端
当我们接受udp协议传输数据并处理数据时的过程:
1.定义UDPSocket服务,通常会监听一个端口,其实就是给这个接受网络应用程序定义数字标识,方便与明确哪些数据过来,该应用程序可以处理
使用DatagramSocket的带参数的对象,此参数传入的一定要是端口号。
DatagramSocket(intport):
创建数据报套接字并将其绑定到本地主机上的指定端口
2.定义一个数据包,因为要存储接受到的字节数据,因为数据包对象中有更多功能可以提取字节数据中的不同数据信息
a)数据:
byte[]buf=newbyte[1024];用来存储数据的空间
b)数据包:
DatagramPacket(byte[]buf,intlength):
构造DatagramPacket,用来接收长度为length的数据包,即(数据空间,所接受的数据长度)
3.通过Socket服务的received方法将收到的数据存入以定义好的数据包中。
DatagramSocket的receive方法.
4.通过数据包对象的特有功能,将这些不同的数据取出,打印在目的地。
常用的方法:
a)byte[]getData():
返回数据缓冲区,即接受的数据
b)InetAddressgetAddress():
返回某台机器的IP地址,此数据报将要发往该机器或者是从该机器接收到的
c)intgetLength():
返回将要发送或接收到的数据的长度。
d)intgetPort():
返回某台远程主机的端口号,此数据报将要发往该主机或者是从该主机接收到的。
5.关闭资源
ds.close();
我们用代码基本演示如下:
import.*;
classUDPRec
{
publicstaticvoidmain(String[]args)throwsException
{
//过程1:
创建一个UDP服务,建立一个绑定主机的端口
DatagramSocketds=newDatagramSocket(8080);
//过程2-1:
定义一个要存储数据的空间
byte[]buf=newbyte[1024];
//过程2-2:
定义一个数据包,存储接受数据,并将之封装成对象
DatagramPacketdp=newDatagramPacket(buf,buf.length);
//过程3:
通过Socket服务将已接受的数据存入到已定义好的数据包中
ds.receive(dp);//阻塞式方法
//过程4:
通过数据包DatagramPacket的特有功能,
//将这些数据包取出来打印在控制台上
Stringip=dp.getAddress().getHostAddress();//获得之际IP号
Stringdata=newString(dp.getData(),0,dp.getLength());//接受数据,和数据长度
intport=dp.getPort();//获得端口号
System.out.println("ip"+ip+".....接受到的数据:
"+data+"来自"+port+"端口号");
//过程5:
关闭资源,
ds.close();
}
}
UDP的应用
我们现在将发送端和接收端写一个聊天小程序。
这个程序分为两部分。
一个是收数据的部分,一个是发数据的部分。
这两个部分要同时执行。
我们需要通过多线程技术。
一个线程控制收,一个线程控制发。
代码演示如下:
import.*;
importjava.io.*;
/*
发送线程
*/
classSendimplementsRunnable
{
privateDatagramSocketds;
publicSend(DatagramSocketds)
{
this.ds=ds;
}
publicvoidrun()
{
try
{
BufferedReaderbr=
newBufferedReader(newInputStreamReader(System.in));
Stringline=null;
while((line=br.readLine())!
=null)
{
if("886".equals(line))
break;
byte[]buf=line.getBytes();
DatagramPacketdp=newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.255"),8080);
ds.send(dp);
}
br.close();
}
catch(Exceptione)
{
thrownewRuntimeException("发送失败");
}
}
}
/*
接受线程
*/
classRecimplementsRunnable
{
privateDatagramSocketds;
publicRec(DatagramSocketds)
{
this.ds=ds;
}
publicvoidrun()
{
try
{
while(true)
{
byte[]buf=newbyte[1024];
DatagramPacketdp=newDatagramPacket(buf,buf.length);
ds.receive(dp);
Stringip=dp.getAddress().getHostAddress();
Stringdata=newString(dp.getData(),0,dp.getLength());
System.out.println("来自"+ip+"的会话:
"+data);
}
}
catch(Exceptione)
{
thrownewRuntimeException("接受失败");
}
}
}
classChatDemo
{
publicstaticvoidmain(String[]args)throwsException
{
DatagramSocketsend=newDatagramSocket();
DatagramSocketrec=newDatagramSocket(8080);
//开启发送线程
newThread(newSend(send)).start();
//开启接受线程
newThread(newRec(rec)).start();
}
}
TCP网络编程
TCP分为客户端和服务端,客户端,它们分别对应的对象是Socket,服务器端对应的是SeverSocket
TCP客户端
通过查阅Socket对象,发现在该对象建立时,就可以去连接指定主机,因为TCP是面向连接的,所以在建立Socket服务时,就要有服务器端存在,并连接成功。
形成通路后,在该通道进行数据的传输。
步骤:
1.建立Socket服务,并指定要连接的主机和端口。
2.获取Socket流中的输出流,将数据写到该流中。
通过网络发送给服务端
3.关闭客户端资源
代码演示
import.*;
importjava.io.*;
classTCPClient
{
publicstaticvoidmain(String[]args)throwsException
{
//创建客户端,指定目的主机和端口号
Socketsoc=newSocket("192.168.1.100",10001);
//为了发送数据,应该获取Socket流中的输出流
OutputStreamout=soc.getOutputStream();
out.write("Helloworldwelcome".getBytes());
soc.close();
}
}
TCP服务端
定义端点接收数据并打印在控制台上。
步骤:
1.建立服务器端的Socket服务,即SeverSocket对象,并监听一个端口
2.获取连接过来的客户端对象。
通过ServerSocket的accpet方法。
没有连接就会等,所以这个方法是阻塞式的。
3.客户端如果发过来数据,那么服务器端要使用对应的客户端对象,并获取到该客户端的读取流来读取发过来的数据。
并打印在控制台上
4.关闭服务端(可选的,一般不会关)。
代码演示:
importjava.io.*;
import.*;
classTCPServer
{
publicstaticvoidmain(String[]args)throwsException
{
//创建服务器
ServerSocketss=newServerSocket(10001);
//使用SeverSocket方法来接受来自于端口的信息
Sockets=ss.accept();
//获得信息来源的主机
Stringip=s.getInetAddress().getHostAddress();
System.out.println(ip+"connect......");
//获得客户端的信息
InputStreamin=s.getInputStream();
byte[]buf=newbyte[1024];
intlen=in.read(buf);
Stringdata=newString(buf,0,len);
System.out.println(data);
ss.close();
}
}
客户端和服务器器交互
客户端和服务器的原理是:
两者都互相在发送信息,即跟人与人打电话一样,有听筒和话筒。
我们用代码来演示下:
importjava.io.*;
import.*;
/*
客户端
*/
classClient
{
publicstaticvoidmain(String[]args)throwsException
{
Sockets=newSocket("192.168.1.100",10009);
//发送给服务器消息
OutputStreamout=s.getOutputStream();
out.write("来自客户端消息:
我来了".getBytes());
//接受服务器消息
InputStreamin=s.getInputStream();
byte[]buf=newbyte[1024];
intlen=in.read(buf);
Stringdata=newString(buf,0,len);
System.out.println(data);
s.close();
}
}
/*
服务器端
*/
classServer
{
publicstaticvoidmain(String[]args)throwsException
{
ServerSocketss=newServerSocket(10009);
System.out.println("等待客户端......");
Sockets=ss.accept();
Stringip=s.getInetAddress().getHostAddress();
System.out.println(ip+"......connect");
//接受客户端消息
InputStreamin=s.getInputStream();
byte[]buf=newbyte[1024];
intlen=in.read(buf);
Stringdata=newString(buf,0,len);
System.out.println(data);
//发送给客户端消息
OutputStreamout=s.getOutputStream();
out.write("来自服务器端的消息:
收到".getBytes());
ss.close();
}
}
网络编程与IO流交互应用:
应用1:
建立一个文本转换器,客户端给服务器端发送文本,服务端会将文本转换成大写再返回给客户端。
而且客户端可以不断的进行文本转换。
当客户端输入over时,转换结束。
服务器也结束。
分析思路:
客户端:
既然是操作设备上的数据,那么就可以使用io技术,并按照io的操作的规律来思考。
源:
键盘录入
目的:
网络设备,网络输出流
而且操作的是文本数据,可以选择字符流。
服务端:
源:
Socket读取流
目的:
Socket输出流
都是文本,装饰
代码演示如下:
import.*;
importjava.io.*;
/*
客户端
*/
classTransClient
{
publicstaticvoidmain(String[]args)throwsException
{
System.out.println("请输入你要转换的字母:
");
Sockets=newSocket("192.168.1.100",9999);
//从键盘上读取字符
BufferedReaderbr=
newBufferedReader(newInputStreamReader(System.in));
//从服务器端接受的信息
BufferedReaderin=
newBufferedReader(newInputStreamReader(s.getInputStream()));
//第一种方式;向服务器端发送信息
//BufferedWriterout=
//newBufferedWriter(newOutputStreamWriter(s.getOutputStream()));
//第二种种方式;向服务器端发送信息
PrintWriterpw=newPrintWriter(s.getOutputStream(),true);
Stringline=null;
while((line=br.readLine())!
=null)
{
if("over".equals(line))
break;
pw.println(line);
//out.write(line);
//out.newLine();//必须换行,否则一直等待
//out.flush();//必须刷新
Stringstr=in.readLine();
System.out.println("sever:
"+str);
}
br.close();
s.close();
}
}
/*
服务器端
*/
classTransServer
{
publicstaticvoidmain(String[]args)throwsException
{
ServerSocketss=newServerSocket(9999);
System.out.println("等待客户端。
。
。
。
。
");
Sockets=ss.accept();
Stringip=s.getInetAddress().getHostAddress();
System.out.println(ip+"......connect");
//第一种方式:
向客户端发送信息
//BufferedWriterout=
//newBufferedWriter(newOutputStreamWriter(s.getOutputStream()));
//第二种方式:
向客户端发送信息
PrintWriterpw=newPrintWriter(s.getOutputStream(),true);
//从客户端接受信息
BufferedReaderin=
newBufferedReader(newInputStreamReader(s.getInputStream()));
Stringline=null;
while((line=in.readLine())!
=null)
{
System.out.println(line);
pw.println(line.toUpperCase());
//out.write(line.toUpperCase());//转换大写
//out.newLine();//必须换行
//out.flush();//必须刷新
}
ss.close();
}
}
该例子出现的问题.
现象:
客户端和服务端都在莫名的等待、
原因:
因为客户端和服务端都有阻塞式方法。
,这些方法没有读到结束标记,那么就一直等待,而导致两端,都在等待。
我们最好在向对方发送消息时,使用PrintWriter对象,因为它可以接受字符和字节,方法println()有自动刷新换行功能。
应用2:
上传文件,建立一个服务器,并给给服务器上传一个文件。
importjava.io.*;
import.*;
classTestClient
{
publicstaticvoidmain(String[]args)throwsException
{
Sockets=newSocket("192.168.1.100",8888);
BufferedReaderbr=newBufferedReader(newFileReader("IPDemo.java"));
BufferedReaderin=
newBufferedReader(newInputStreamReader(s.getInputStream()));
PrintWriterout=newPrintWriter(s.getOutputStream(),true);
Stringline=null;
while((line=br.readLine())!
=null)
{
out.println(line);
}
//out.println("over");//结束标记1,否则一直读取
s.shutdownOutput();//
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 编程