网络编程.docx

上传人:b****6 文档编号:6026365 上传时间:2023-01-03 格式:DOCX 页数:24 大小:23.44KB
下载 相关 举报
网络编程.docx_第1页
第1页 / 共24页
网络编程.docx_第2页
第2页 / 共24页
网络编程.docx_第3页
第3页 / 共24页
网络编程.docx_第4页
第4页 / 共24页
网络编程.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

网络编程.docx

《网络编程.docx》由会员分享,可在线阅读,更多相关《网络编程.docx(24页珍藏版)》请在冰豆网上搜索。

网络编程.docx

网络编程

网络编程

网络编程基础

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();//

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1