计网TCPUDP客户端和服务器通信编程.docx
- 文档编号:7108426
- 上传时间:2023-01-18
- 格式:DOCX
- 页数:12
- 大小:915.82KB
计网TCPUDP客户端和服务器通信编程.docx
《计网TCPUDP客户端和服务器通信编程.docx》由会员分享,可在线阅读,更多相关《计网TCPUDP客户端和服务器通信编程.docx(12页珍藏版)》请在冰豆网上搜索。
计网计网TCPUDP客户端和服务器通信编程客户端和服务器通信编程计算机网络第二次实验智能1402班201408070221李帅玲目录一实验目的1二实验原理11.TCP原理12.UDP原理2三实验步骤及分析31.实验实现流程32.TCPClient代码实现及说明:
43.TCPServer代码及说明54.UDPClient代码及说明65.UDPServer代码及说明76.问题回答8四实验总结91.发生的服务器二次运行错误解释:
92.关于TCP和UDP传输不同点的思考:
9一一实验目的实验目的1.熟练掌握UDP、TCPClient/Server模式的通信原理、2.实验内容如下:
二实验原理二实验原理1.TCP原理原理TCP是一种面向连接的、可靠的传输层协议。
面向连接是指一次正常的TCP传输需要通过在TCP客户端和TCP服务端建立特定的虚电路连接来完成,该过程通常被称为“三次握手”。
可靠性可以通过多种方法来提供保证(快速重传和回退N步),在这里我们关心的是数据序列和确认。
一个TCP连接的套接字对包含四元组(本地IP地址,本地端口号,目的IP地址,目的端口号)一个套接字包含一个IP地址和一个端口号。
服务器为了能对客户机程序发起的连接做出响应,必须在客户机程序试图发起连接之前,作为一个进程在系统中运行。
客户机/服务器应用程序传输过程:
当服务器进程运行时,客户机进程可以向服务器发起一个TCP连接。
在客户机程序中,通过创建一个套接字来完成。
当客户机创建它的套接字时,它指定服务器进程的地址,即服务器的IP地址和进程的端口号。
一旦在客户机程序中生成套接字,客户机的TCP与服务器的TCP发起三次握手并建立一个TCP连接。
这个三次握手发生在运输层,对于客户机程序和服务器程序是完全透明的。
在三次握手期间,当服务器接受到客户机的套接字时,将为特定的客户机程序创建一个新的套接字。
TCP传输流程图:
2.UDP原理原理UDP是面向报文的不可靠传输。
UDP是一种无连接的服务,即在两个进程间没有创建管道时所需的初始握手阶段。
因为UDP没有管道,所以当一个进程需要向另一个发送一批字节时,该发送进程需要为这批字节附上目的进程地址和目的端口号(TCP传输的字节不需要)。
并且,该进程对于每批由发送进程所发送的字节都必须重复做。
UDP目的地址由二元组组成(目的IP地址,目的端口号),带有IP目的地址和端口号的批字节数据称为分组。
UDP提供了一种不可靠面向报文的服务模型,它尽力而为地向目的交付这批字节,但不保证这批字节的确能被交付。
UDP是面向报文的,是旨在发送方单次操作所发送的一批字节在接收方作为一个批次来交付,这与TCP的字节流语义形成对照。
UDP是尽力而为的,UDP传输流程图:
三实验步骤及分析三实验步骤及分析1.实验实现流程实验实现流程客户机/服务器应用程序使用面向连接的运输服务案例:
(1)一台服务机从其标准输入(键盘)读取一行字符,并通过其套接字将该行发送到服务器。
(2)服务器从其连接套接字读取一行字符。
(3)服务器将该字符转换成大写。
(4)服务器将修改后的行通过其连接套接字再回发给客户机。
(5)客户机从其套接字中读取修改后的行,然后将该行在其标准输出(监视器)上打印出来。
2.TCPClient代码实现及说明:
代码实现及说明:
packageshiyan2;importjava.io.*;import.*;publicclassTCPClientpublicstaticvoidmain(Stringargv)throwsException/*参数说明*sentence用户输入的发送到服务器的字符串*modifiedSentence从服务器得到并发送到用户标准输出的字符串*inFromUser输入流,连接到标准输入,键盘输入的字符流入它*inFromClient输入流,连接到客户端套接字,从网络来的字符流入它;*outToServer输出流,连接到套接字,客户端发送到网络的字符流入它*clientSocket套接字,包含目的服务器IP地址和端口号*/Stringsentence;StringmodifiedSentence;/创建用户输入流BufferedReaderinFromUser=newBufferedReader(newInputStreamReader(System.in);/通过套接字创建TCP连接,localhost为服务器主机名(此处服务器为本地主机),/客户端通过主机名获取主机IP地址,1234为端口号SocketclientSocket=newSocket(localhost,1234);/创建连接到套接字的输入输出流DataOutputStreamoutToServer=newDataOutputStream(clientSocket.getOutputStream();BufferedReaderinFromServer=newBufferedReader(newInputStreamReader(clientSocket.getInputStream();/从键盘读取字符串sentence=inFromUser.readLine();/将字符串输入输出流,字符经套接字流入TCP管道outToServer.writeBytes(sentence+n);/接收来自服务器的字符modifiedSentence=inFromServer.readLine();/字符输出到屏幕System.out.println(Fromserver:
+modifiedSentence);/关闭套接字,同时关闭客户端和服务器之间的TCP连接(此时客户机的TCP向服务器的TCP发送一个挥手报文)clientSocket.close();3.TCPServer代码及说明代码及说明packageshiyan2;importjava.io.*;import.*;publicclassTCPServerpublicstaticvoidmain(Stringargv)throwsException/*参数说明*clientSentence服务器接受客户端发送来的字符串*capitalizedSentence转换成大写字母后的字符串*inFromClient输入流,连接到套接字,客户端发送过来的字符流入它*outToClient输出流,连接到套接字,服务器发送给客户端的字符流入它*welcomeSocket监听用的套接字,包含服务器端口号1234*connectionSocket新套接字,用于与客户端TCP建立连接,其端口号也为1234*/StringclientSentence;StringcapitalizedSentence;/审查请求连接的用户端其TCP目的端口号是否为1234ServerSocketwelcomeSocket=newServerSocket(1234);while(true)/保证一次建立多次与客户端通信SocketconnectionSocket=welcomeSocket.accept();/创建输入输出流BufferedReaderinFromClient=newBufferedReader(newInputStreamReader(connectionSocket.getInputStream();DataOutputStreamoutToClient=newDataOutputStream(connectionSocket.getOutputStream();clientSentence=inFromClient.readLine();capitalizedSentence=clientSentence.toUpperCase()+n;outToClient.writeBytes(capitalizedSentence);TCP运行结果:
先运行TCPServer之后再运行TCPClient如图,客户端向服务器发送报文段“abcdef”后,服务器将字符转换成大写字母后再发送回来。
4.UDPClient代码及说明代码及说明packageshiyan2;importjava.io.*;import.*;publicclassUDPClientpublicstaticvoidmain(Stringargv)throwsException/*参数说明*inFromUser输入流,连接到标准输入,键盘输入的字符流入它*clientSocket套接字,包本地端口号*IPAddress目的服务器IP地址*sendData客户端发送的字符串*receiveData客户端接收的字符串*sentence键盘输入的字符串*sendPacket发送的数据报文(数据,数据长度,目的IP地址,目的端口号)*receivePacket接收的数据报文(数据,数据长度)*/BufferedReaderinFromUser=newBufferedReader(newInputStreamReader(System.in);/DatagramSocket类型,因为UDP是面向报文的,不同于TCPSocket类型的套接字/创建套接字,此处没有发起TCP连接,所以不需要把服务器主机名或端口号作为参数/此种方式,运输层将自动为该套接字分配一个端口号,但不会给服务器自动分配一个套接字DatagramSocketclientSocket=newDatagramSocket();/此种方式,设置客户端端口号为5432/DatagramSocketclientSocket=newDatagramSocket(5432);/获取服务器IP地址InetAddressIPAddress=InetAddress.getByName(localhost);/创建发送和接受字符串参数bytesendData=newbyte1024;bytereceiveData=newbyte1024;/读取键盘输入的字符串并存入字符数组Stringsentence=inFromUser.readLine();sendData=sentence.getBytes();/构造数据报文(数据,数据长度,目的IP地址,目的端口号)DatagramPacketsendPacket=newDatagramPacket(sendData,sendData.length,IPAddress,2345);/通过套接字发送数据报文clientSocket.send(sendPacket);/创建接收服务器发送来的数据的参数DatagramPacketreceivePacket=newDatagramPacket(receiveData,receiveData.length);/通过套接字接收数据分组并存放到receivePacketclientSocket.receive(receivePacket);/转换成字符串并输出StringmodifiedSentence=newString(receivePacket.getData();System.out.println(fromserver:
+modifiedSentence);/关闭套接字,无需向服务器发送运输层报文clientSocket.close();5.UDPServer代码及说明代码及说明packageshiyan2;importjava.io.*;import.*;publicclassUDPServerpublicstaticvoidmain(Stringargv)throwsException/*参数说明*serverSocket套接字,包含端口号*sendData发送的字符串*receiveData接收的字符串*receivePacket获取的数据报文(数据,数据长度)*sentence从数据报文中拆分出的字符串*IPAddress从数据报文中拆分出客户端的IP地址*port从数据报文中拆分出的客户端的端口号,客户端与服务器的端口号是不同的*capitalizedSentence将字符串转换成大写字母*/套接字,服务器端口号为2345DatagramSocketserverSocket=newDatagramSocket(2345);bytesendData=newbyte1024;bytereceiveData=newbyte1024;while(true);/获取数据报文DatagramPacketreceivePacket=newDatagramPacket(receiveData,receiveData.length);serverSocket.receive(receivePacket);/拆分数据报文Stringsentence=newString(receivePacket.getData();InetAddressIPAddress=receivePacket.getAddress();intport=receivePacket.getPort();/字符转换成大写字母StringcapitalizedSentence=sentence.toUpperCase();sendData=capitalizedSentence.getBytes();/发送数据报文,没有建立连接所以需要知道客户端IP和端口号DatagramPacketsendPacket=newDatagramPacket(sendData,sendData.length,IPAddress,port);serverSocket.send(sendPacket);UDP运行结果:
同样先运行UDPServer.java再运行UDPClient.java结果如图,服务器发回的数据后面那串符号,应该是我软件的问题。
6.问题回答问题回答24.a如果在运行TCPServer之前运行TCPClient,则客户端发送的请求将没有回应,因为服务器为了能够欧接收并回答客户的报文,它必须准备好并已经在运行,而先运行TCPClient服务器还没有准备好。
24.b与上述同理。
24.c如果使用了客户端和服务器端使用了不同端口,则TCP客户端在发送请求的时候会报错,即无法连接;而UDP客户端在发送请求的时候不会报错(因为它不需要与服务器建立连接),但是其请求将得不到处理。
有意思的是,因为之前在本机运行了一个端口号为2347的TCP服务器程序,而当我的UDP客户端的目的端口号也设置为2347,而不是UDP服务器的端口号2345时,UDP的请求也得到了处理,估计是它碰巧的和TCP的服务器建立了连接。
2.5UDPClient中使用DatagramSocketclientSocket=newDatagramSocket(5432);代替DatagramSocketclientSocket=newDatagramSocket();UDPServer中不需要更改端口号,前面一行代码为创建客户端的套接字,其端口号为5432,而第二行代码只是为客户端创建套接字,但其端口号为运输层分配的默认端口号,无论哪种对服务器端套接字的创建没有影响:
DatagramSocketserverSocket=newDatagramSocket(2347);这只是它的端口号,而对于服务器发送的数据报文;DatagramPacketsendPacket=newDatagramPacket(sendData,sendData.length,IPAddress,port);其中的客户端端口号port是从数据报文中拆分出来的,所以如果客户端的端口号变为周知端口号了,那么此处的端口号自然也会改变的。
此时UDPServer的端口号为2347,UDPClient的端口号为5432,而变化之前,UDPServer的端口号为2347,UDPClient的端口号为运输层默认的端口号。
四实验总结四实验总结1.发生的服务器二次运行错误解释:
发生的服务器二次运行错误解释:
通信时两个进程之间好像有一条管道,这条管道一直保持,除非其中一个进程关闭它。
此处因为服务器运行一次以后代码中是创立了多线程,即运行一次以后除非关闭程序,否则此服务器程序将会一直运行,否则如果再次运行此服务器程序,将会出现程序占用的报错。
2.关于关于TCP和和UDP传输不同点的思考:
传输不同点的思考:
(1)TCP是面向连接的而UDP是无连接的,TCP发送的是数据流,而UDP发送的是数据块TCP有两个套接字,一个是监听套接字,用于监听客户端发送的请求是否是面向本服务器的,另一个是传输套接字,是用于建立传输连接的,该套接字与客户端的套接字建立连接后,相当于在客户端和服务器之间建立了一个管道,两者通过该管道源源不断的传输数据。
所以TCP用户端至少有两个连接套接字的数据流,一个输出流用于将客户端的数据报文通过套接字输出到TCP通道,一个输入流,将管道的数据报文通过套接字输入给TCP客户端的。
而TCP服务器同样也有一个输出流,将数据报文通过套接字进入管道发送给客户端,还有一个输入流,将管道的数据报文通过套接字输入进来。
而UDP是没有建立连接的,所以UDP的服务器只有一个传输数据的套接字。
而且客户端和服务器只是将数据报文分块发送而不是流的形式,而每发送一次客户端和服务器都需要将目的端口和目的IP地址封装到数据报文里,这是与TCP不同的地方,TCP建立连接以后普哦,服务器在发送数据报文的时候有就不要记录目的地址和端口,直接通过管道传输即可。
UDP的传输也只是尽力而为的传输,不保证数据一定能安全到达目的地。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- TCPUDP 客户端 服务器 通信 编程