计算机网络原理实验报告 基于TCPUDP的Socket编程
- 格式:doc
- 大小:688.00 KB
- 文档页数:8
TCP和UDP客户端及服务器端实验报告一、原理1.基于TCP协议的服务器端程序流程:1)创建套接字(socket)2)绑定套接字(bind)3)将套接字设为监听,准备接收客户请求(listen)4)等待客户请求的到来,当请求到来后,接受请求,返回一个对应于此次连接的套接字(accept)5)用返回的套接字与客户端进行通信(send/recv)6)返回,等待另一客户请求7)关闭套接字2.基于TCP协议的客户端程序流程1)创建套接字(socket)2)向服务器发出连接请求(connect)3)和服务器端进行通信(send/recv)4)关闭套接字在服务器端调用accept函数时,程序就会等待客户端调用connect函数发出连接请求,然后接收请求,于是双方就建立了连接,之后,服务器端和客户端就可以利用send和recv函数进行通信了。
3.基于UDP的服务器端编写1)创建套接字(socket)2)绑定(bind)3)等待接收数据(recvfrom)4)关闭套接字4.基于UDP的客户端编写1)创建套接字(socket)2)向服务器发送数据(sendto)3)关闭套接字在所有的套接字编程中第一步都是加载套接字库(WSAStartup)对于每一个WSAStartup函数的成功调用,在最后都要对应一个WSACleanUp调用。
TCP代码实现:首先要建两个工程,不妨设为tcpsrv和tcpclient,分别为客户端和服务器端tcpsrv.cpp//TCP server//listen port 9102//receive string and display it//Visual C++ 6.0#include <stdio.h>#include <winsock2.h>#pragma comment(lib,"ws2_32.lib")#define BUFLEN 1024int main(){SOCKET serversoc;SOCKET clientsoc;SOCKADDR_IN serveraddr;SOCKADDR_IN clientaddr;char buf[BUFLEN];int len;WSADATA wsa;WSAStartup(MAKEWORD(1,1),&wsa);//initial Ws2_32.dll by a processif((serversoc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 0)//create a tcp socket {printf("Create socket fail!\n");return -1;}serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(9102);serveraddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);if(bind(serversoc, (SOCKADDR *)&serveraddr, sizeof(serveraddr)) != 0){printf("Bind fail!\n");return -1;}//start listen, maximum length of the queue of pending connections is 1printf("Start listen...\n");if(listen(serversoc, 1) != 0){printf("Listen fail!\n");return -1;}len = sizeof(SOCKADDR_IN);//waiting for connectingif((clientsoc = accept(serversoc, (SOCKADDR *)&clientaddr, &len))<=0) {printf("Accept fail!\n");return -1;}printf("Connected\n");while(1){//waiting for data receiveif(recv(clientsoc, buf, BUFLEN, 0) <= 0){//some error occurprintf("Close connection\n");closesocket(clientsoc);break;}printf("%s\n",buf);}WSACleanup(); //clean up Ws2_32.dllreturn 0;}相应的客户端程序,tcpclient.cpp//TCP client//client send string to server//Visual C++ 6.0#include <stdio.h>#include <winsock2.h>#pragma comment(lib,"ws2_32.lib")int main(){SOCKET soc;SOCKADDR_IN serveraddr;SOCKADDR_IN clientaddr;unsigned char buf[1024];WSADATA wsa;WSAStartup(MAKEWORD(1,1),&wsa);//initial Ws2_32.dll by a processif((soc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 0)//create a tcp socket {printf("Create socket fail!\n");return -1;}serveraddr.sin_family = AF_INET;serveraddr.sin_port = htons(9102);serveraddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//connect to serverprintf("Try to connect...\n");if(connect(soc, (SOCKADDR *)&serveraddr, sizeof(serveraddr)) != 0){printf("Connect fail!\n");return -1;}printf("Connected\n");while(1){scanf("%s", buf);//send to serverif(send(soc, buf, strlen(buf)+1, 0)<=0){printf("Error!\n");}}WSACleanup(); //clean up Ws2_32.dllreturn 0;}UDP服务器端://UDP server//listen port 9102//receive string and display it//Visual C++ 6.0#include <stdio.h>#include <winsock2.h>#pragma comment(lib,"ws2_32.lib")#define BUFLEN 1024int main(void){SOCKET soc;SOCKADDR_IN addr;char buf[BUFLEN];int len;WSADATA wsa;WSAStartup(MAKEWORD(1,1),&wsa);//initial Ws2_32.dll by a process memset(&addr, 0, sizeof(addr));if((soc = socket(AF_INET,SOCK_DGRAM,0)) <= 0){printf("Create socket fail!\n");return -1;}addr.sin_family = AF_INET;addr.sin_port = htons(9102);addr.sin_addr.s_addr = htonl(INADDR_ANY);if(bind(soc,(struct sockaddr *)&addr,sizeof(struct sockaddr))!=0){printf("Bind fail!\n");return -1;}len = sizeof(addr);printf("start listen...\n");while(1) {recvfrom(soc, buf, BUFLEN, 0,(struct sockaddr*)&addr, &len);printf("%s\n",buf);}WSACleanup(); //关闭return 0;}客户端://UDP client//client send string to server//Visual C++ 6.0#include <stdio.h>#include <winsock2.h>#pragma comment(lib,"ws2_32.lib")#define BUFLEN 1024int main(void){SOCKET soc;SOCKADDR_IN addr;unsigned char buf[BUFLEN];WSADATA wsa;WSAStartup(MAKEWORD(2,2),&wsa);//initial Ws2_32.dll by a processmemset(&addr, 0, sizeof(addr));if((soc = socket(AF_INET,SOCK_DGRAM,0)) <= 0){printf("Create socket fail!\n");return -1;}addr.sin_family = AF_INET;addr.sin_addr.s_addr = inet_addr("127.0.0.1");addr.sin_port = htons(9102);bind(soc,(struct sockaddr *)&addr,sizeof(addr));while(1) {scanf("%s", buf);sendto(soc, buf, strlen(buf)+1, 0, (struct sockaddr *)&addr, sizeof(addr));}WSACleanup();//clean up Ws2_32.dllreturn 0;}。
socket编程实验报告《Socket编程实验报告》在计算机网络通信中,Socket编程是一种常见的通信方式,它可以在不同的计算机之间实现数据的传输和通信。
本次实验旨在通过Socket编程实现一个简单的客户端和服务器端通信,并对其进行测试和分析。
实验环境:- 操作系统:Windows 10- 开发工具:Visual Studio Code- 编程语言:Python实验步骤:1. 设计客户端和服务器端的通信协议2. 编写客户端和服务器端的代码3. 运行客户端和服务器端,并进行通信测试4. 分析通信过程中的数据传输情况实验结果:经过实验,我们成功实现了一个简单的客户端和服务器端通信程序。
在测试过程中,我们发现数据可以正常地在客户端和服务器端之间传输,而且通信过程稳定可靠。
分析:通过本次实验,我们深入了解了Socket编程的基本原理和实现方式。
Socket编程可以灵活地实现不同计算机之间的通信,为网络通信提供了重要的技术支持。
在实际应用中,Socket编程可以用于实现各种网络通信功能,如网页浏览、文件传输、视频流等。
总结:通过本次实验,我们对Socket编程有了更深入的了解,并掌握了基本的编程技巧和调试方法。
Socket编程是网络通信中的重要技术,对于计算机网络领域的学习和应用具有重要的意义。
希望通过今后的实践和学习,我们能够进一步深化对Socket编程的理解,为网络通信技术的发展做出贡献。
通过本次实验,我们对Socket编程有了更深入的了解,并掌握了基本的编程技巧和调试方法。
Socket编程是网络通信中的重要技术,对于计算机网络领域的学习和应用具有重要的意义。
希望通过今后的实践和学习,我们能够进一步深化对Socket编程的理解,为网络通信技术的发展做出贡献。
一、概述TCP(传输控制协议)和UDP(用户数据报协议是网络体系结构TCP/IP模型中传输层一层中的两个不同的通信协议。
TCP:传输控制协议,一种面向连接的协议,给用户进程提供可靠的全双工的字节流,TCP套接口是字节流套接口(ST ream socket)的一种。
UDP:用户数据报协议。
UDP是一种无连接协议。
UDP套接口是数据报套接口(datagram Socket)的一种。
二、TCP和UDP介绍1)基本TCP客户—服务器服务器服务器是指在网络环境下运行相应的应用软件,为网上用户提供共享信息资源和各种服务的一种高性能计算机,英文名称叫做Server。
[全文]程序设计基本框架说明:(三次握手)1.客户端发送一个SYN段(同步序号)指明客户打算连接的服务器服务器服务器是指在网络环境下运行相应的应用软件,为网上用户提供共享信息资源和各种服务的一种高性能计算机,英文名称叫做Server。
端口,以及初始化序号(ISN) 。
2.服务器发回包含服务器的初始序号的SYN报文段作为应答。
同时,将确认序号(ACK)设置为客户的ISN加1以对客户的SYN 报文段进行确认。
一个SYN将占用一个序号。
3.客户必须将确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认。
2) 基本TCP客户—服务器程序设计基本框架流程图3) UDP和TCP的对比:从上面的流程图比较我们可以很明显的看出UDP没有三次握手过程。
简单点说。
UDP处理的细节比TCP少。
UDP不能保证消息被传送到(它也报告消息没有传送到)目的地。
UDP也不保证数据包的传送顺序。
UDP把数据发出去后只能希望它能够抵达目的地。
TCP优缺点:优点:1.TCP提供以认可的方式显式地创建和终止连接。
2.TCP保证可靠的、顺序的(数据包以发送的顺序接收)以及不会重复的数据传输。
3.TCP处理流控制。
4.允许数据优先5.如果数据没有传送到,则TCP套接口返回一个出错状态条件。
Socket编程实验⼀、实验⽬的了解Socket通信的概念,掌握Socket通信的编程⽅法理解TCP和UDP协议的⼯作原理与⼯作过程编写基于TCP和UDP的客户/服务器的程序,来了解两者的⼯作流程要求能够在⾃⼰的电脑上运⾏程序并进⾏数据传输⼆、实验内容阅读API编程 PPT。
了解 socket 编程的基本知识。
编写基于 TCP 的客户/服务器程序。
编写基于 UDP 的客户/服务器程序。
三、实验原理C 库中包含了⽤语⽹络通信的 socket 套接字。
Socket 套接字分为流式套接⼝、数据报套接⼝及原始套接⼝ 3 类,本实验中将涉及到前两者:流式套接⼝定义了⼀种可靠的⾯向连接的服务,实现了⽆差错⽆重复的顺序数据传输(TCP)。
数据报套接⼝定义了⼀种⽆连接的服务,数据通过相互独⽴的报⽂进⾏传输,是⽆序的,并且不保证可靠,⽆差错(UDP)。
四、实验步骤(⼀)基于UDP的客户/服务器编写(⼆)基于TCP的客户/服务器编写五、实验结果及分析(⼀)基于UDP的客户/服务器客户端代码from socket import *serverName = 'localhost'serverPort = 12000clientSocket = socket(AF_INET, SOCK_DGRAM)message = input()clientSocket.sendto(message.encode(), (serverName, serverPort))modifiedMessage, serverAddress = clientSocket.recvfrom(2048)print('From Server: ', modifiedMessage.decode())clientSocket.close()服务器端代码from socket import *serverPort=12000serverSocket=socket(AF_INET,SOCK_DGRAM)serverSocket.bind(('',serverPort))print("The srever is ready to receive")while True:message,clientAddress=serverSocket.recvfrom(2048)modifiedMessage=message.decode().upper()serverSocket.sendto(modifiedMessage.encode(),clientAddress)测试结果(⼆)基于TCP的客户/服务器编写客户端代码from socket import *serverName = 'localhost'serverPort = 12000clientSocket = socket(AF_INET, SOCK_STREAM)clientSocket.connect((serverName, serverPort))sentence = input()clientSocket.send(sentence.encode())modifiedSentence = clientSocket.recv(1024)print('From Server: ', modifiedSentence.decode())clientSocket.close()服务器端代码from socket import *serverPort = 12000serverSocket = socket(AF_INET,SOCK_STREAM)serverSocket.bind(('',serverPort))serverSocket.listen(1)print('The server is ready to receive')while True:connectionSocket, addr = serverSocket.accept()sentence = connectionSocket.recv(1024)capitalizedSentence = sentence.upper()connectionSocket.send(capitalizedSentence)connectionSocket.close()测试结果七、实验⼼得体会通过该实验,了解了socket编程的基本⽅法,学习了利⽤TCP和UDP进⾏简单的数据传输。
计算机网络实验一:socket文件传输一、实验目地1、了解网络通信原理。
掌握客户端/服务器程序设计。
2、理解Socket通信原理,掌握使用ServerSocket类和Socket类进行TCPSocket通信的程序设计方法二、实验原理Socket可以看成在两个程序进行通讯连接中的一个端点,是连接应用程序和网络驱动程序的桥梁,Socket在应用程序中创建,通过绑定与网络驱动建立关系。
此后,应用程序送给Socket的数据,由Socket交网络驱动程序向网络上发送出去。
计算机从网络上收到与该Socket绑定IP地址和端口号相关的数据后,由网络驱动程序交给Socket,应用程序便可从该Socket中提取接收到得数据,网络应用程序就是这样通过Socket进行数据的发送与接收的。
详细如图:我们来分析一下图,Host A上的程序A将一段信息写入Socket中,Socket 的内容被Host A的网络管理软件访问,并将这段信息通过Host A的网络接口卡发送到Host B,Host B的网络接口卡接收到这段信息后,传送给Host B 的网络管理软件,网络管理软件将这段信息保存在Host B的Socket中,然后程序B才能在Socket中阅读这段信息。
Socket套接口有3种类型。
1.SOCK_STREAM流式套接口,面向连接的,可靠地,TCP。
2.SOCK_DRAM数据报套接口,面向无连接,不可靠,UDP。
3.原始套接口,主要用于新的网络协议实现的测试三、实验分析1、实验要求、按需求编写服务器端和客户端程序代码。
实现:(1)服务器端向客户端提供文件目录。
(2)客户端向服务器端发出请求下载文件。
(3)客户端向服务器端上传文件。
2、Socket通信工作过程如下(1)、建立连接服务器(ServerSocket)监听指定端口,看是否有客户端的连接请求;客户端(ClientServer)创建套接字并通过指定端口请求与服务器建立连接。
Socket编程实验报告一、程序代码(1)服务器端#include <stdio.h>#include <Winsock2.h>#pragma comment(lib, "ws2_32.lib")void main(){ WORD wVersionRequested;WSADATA wsaData;int err;wVersionRequested = MAKEWORD( 1, 1 );err = WSAStartup( wVersionRequested, &wsaData );if ( err != 0 ) { return; }if ( LOBYTE( wsaData.wVersion ) != 1 ||HIBYTE( wsaData.wVersion ) != 1 ){ WSACleanup( );return; }SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);SOCKADDR_IN addrSrv;addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);addrSrv.sin_family=AF_INET;addrSrv.sin_port=htons(6000);bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));// 绑定端口listen(sockSrv,SOMAXCONN); //SOMAXCONN由系统确定请求数SOCKADDR_IN addrClient;// 连接上的客户端ip地址int len=sizeof(SOCKADDR);while(1){SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);// 接受客户端连接,获取客户端的ip地址char sendBuf[50];sprintf(sendBuf,"Welcome %s tohere!",inet_ntoa(addrClient.sin_addr));// 组合消息发送出去send(sockConn,sendBuf,strlen(sendBuf)+1,0);// 发送消息到客户端char recvBuf[50]; recv(sockConn,recvBuf,50,0);// 接受客户端消息printf("%s\n",recvBuf);closesocket(sockConn);WSACleanup();//断开连接}}(2)客户端代码#include <stdio.h>#include <Winsock2.h>#pragma comment(lib, "ws2_32.lib")void main(){WORD wVersionRequested;WSADATA wsaData;//WSAata用来存储系统传回的关于WinSocket的资料。
winsock编程实验报告Winsock编程实验报告引言:Winsock(Windows Socket)是一种用于网络通信的编程接口,常用于开发基于TCP/IP协议的应用程序。
本篇文章将介绍我对Winsock编程的实验经历和心得体会。
实验目的:通过Winsock编程实验,深入了解网络通信原理和技术,掌握基于TCP/IP协议的应用程序开发方法。
实验环境:本次实验在Windows操作系统下进行,使用了Visual Studio 2019作为开发工具。
实验过程:1. 实验一:建立基于TCP的客户端/服务器通信在这个实验中,我首先创建了一个服务器程序和一个客户端程序。
服务器程序使用Winsock库函数创建了一个套接字,并绑定到指定的IP地址和端口上。
客户端程序通过Winsock库函数创建了一个套接字,并连接到服务器的IP地址和端口上。
通过这个实验,我学会了如何建立基于TCP的客户端/服务器通信。
2. 实验二:实现基于UDP的数据传输在这个实验中,我创建了一个基于UDP的数据传输程序。
UDP是一种无连接的传输协议,相对于TCP来说,它更加轻量级,适用于一些对数据可靠性要求不高的应用场景。
通过这个实验,我学会了如何使用Winsock库函数实现基于UDP的数据传输。
3. 实验三:实现多线程服务器在这个实验中,我将服务器程序改为多线程模式。
通过创建多个线程,服务器可以同时处理多个客户端的请求,提高了系统的并发性能。
这个实验让我更加深入地理解了多线程编程和网络通信的结合。
实验结果与分析:通过以上实验,我成功地实现了基于TCP和UDP的网络通信,并且在实验三中实现了多线程服务器。
在实验过程中,我遇到了一些问题,比如套接字的创建和绑定、连接的建立和断开等。
但通过查阅文档和调试,我最终解决了这些问题。
实验结果表明,Winsock编程是一种强大且灵活的工具,可以满足各种网络通信需求。
实验心得:通过本次实验,我对Winsock编程有了更深入的了解。
实验三、WINSOCK套接字编程实验报告序号:姓名:刘易学号: 20101150040 成绩指导老师:1.实验目的:用C或JA V A语言编写客户端、服务器程序,实现基于TCP或UDP的网络通信数据传输服务,熟悉基于TCP或UDP的Socket编程原理。
2.实验环境:建立在TCP/IP 网络体系结构之上计算机网络实验环境。
各计算机除了安装TCP/IP 软件外,还安装了TCP/IP 开发系统。
计算机具备Windows环境中套接字socket 的编程接口功能,可为用户提供全网范围的进程通信功能。
3.实验指导:参见套接字编程实验指导4.实验步骤(1)运行指导书中给出的参考程序,分析实验结果,并回答问题(1)-(3)(2)根据给定参考程序修改代码,完善修改服务器和客户端的功能。
并回答问题(4)-(5)5.实验结果分析(1)为什么在服务器和客户端要包含winsock2.h文件?(2)为什么在服务器和客户端程序中要加入#pragma comment(lib,"ws2_32.lib") 语句,如果不加会出现什么问题?(3)为什么在服务器和客户端程序中要使用WSAStartup函数,如果不用,程序会有什么问题?(4)修改后的程序完成实现了什么功能,附上修改后的源代码。
(修改或填加的代码用波浪线标注,并填加注释),并附上实验截图客户端改变的代码:{ for(;;){memset(buf, 0, 1024);printf("Please input a line to server:");scanf("%s",&buf);rval = send(fd, buf, strlen(buf) + 1,0);if(rval < 0)printf("Write error!");if((rval=recv(fd,buf,sizeof(buf),0)<0))perror("reading stream message");if(rval==0)printf("server said :%s\n",buf);}服务器端修改的代码:for(;;){memset(buf, 0, sizeof(buf));if ( (rval = recv(msgsock, buf, sizeof(buf),0) < 0))perror("reading stream message");if (rval == 0)printf("client said :%s\n",buf);printf("server-->");scanf("%s",&buf);rval=send(msgsock,buf,strlen(buf)+1,0);}}(5)请详细说明此实验在设计及运行时遇到的问题和解决办法,及实验体会及建议。
实验报告实验课程名称:通信软件基础实验课学院:软件工程学院专业:软件工程指导教师:报告人姓名:学号:班级:学期:2021实验成绩实验项目名称基于WinSock的简单TCP网络编程一、实验目的与要求:1、学习和掌握Socket编程的面向连接编程模型。
2、学习和掌握基于WinSock的TCP网络编程方法。
二、实验设备及软件:笔记本电脑、Window 7操作系统、Microsoft Visual Studio 2012三、实验方法(原理、流程图)流程图:四、实验过程、步骤及内容实验代码:server.h#define MAX_CLIENT 10 //同时服务的client数目上限#define MAX_BUF_SIZE 65535 //缓存区的大小const u_short UDPSrvPort = 2345; //Server的UDP端口const char START_CMD[] = "START";const char GETCURTIME_CMD[] = "GET CUR TIME";//传递给TCP线程的结构化参数struct TcpThreadParam{SOCKET socket;sockaddr_in addr;};DWORD WINAPI TcpServeThread(LPVOID lpParam); //TCP线程的线程函数DWORD WINAPI UdpServer(LPVOID lpParam); //UDP服务器线程server.cpp#include"stdafx.h"#include"iostream.h"#include"stdio.h"#include"string.h"#include"time.h"#include"WinSock2.h"#include"Windows.h"#include"server.h"#pragma comment (lib, "Ws2_32.lib")#pragma pack(1) //结构在存储时按字节对齐long TcpClientCount = 0;int main(int argc, char* argv[]){////检查命令行参数//if(argc != 2)//{// cerr << "Worng format!\nCorrect usage: Server.exe <TCP server port>";// return -1;//}//初始化winsock2环境WSADATA wsa;if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0){cerr << "\nFailed to initialize the winsock 2 stack\n"<< "error code: " << WSAGetLastError() << endl;return -1;}//创建UDP服务器DWORD dwThreadId;CreateThread(NULL, 0, UdpServer, NULL, 0, &dwThreadId);//创建用于侦听的TCP Server SocketSOCKET ListenSocket = socket(AF_INET, SOCK_STREAM, 0);//获取TCP监听端口号u_short ListenPort = (u_short)atoi(argv[1]);//获取本机名char hostname[256];gethostname(hostname, sizeof(hostname));//获取本地IP地址hostent *pHostent = gethostbyname(hostname);//填充本地TCP Socket地址结构SOCKADDR_IN ListenAddr;memset(&ListenAddr, 0, sizeof(SOCKADDR_IN));ListenAddr.sin_family = AF_INET;ListenAddr.sin_port = htons(ListenPort);ListenAddr.sin_addr = *(in_addr*)pHostent->h_addr_list[0];//绑定TCP端口if (bind(ListenSocket, (sockaddr*)&ListenAddr, sizeof(ListenAddr)) == SOCKET_ERROR) {cerr << "\nFailed to bind the ListenSocket\n"<< "error code: " << WSAGetLastError() << endl;return -1;}//监听if ((listen(ListenSocket, SOMAXCONN)) == SOCKET_ERROR){cerr << "\nFailed to listen the ListenSocket\n"<< "error code: " << WSAGetLastError() << endl;return -1;}cout << "TCP Server Started On TCP Port: "<< ListenPort << endl << endl;SOCKET TcpSocket;SOCKADDR_IN TcpClientAddr;while (TRUE){//接受客户端连接请求int iSockAddrLen = sizeof(sockaddr);if((TcpSocket = accept(ListenSocket, (sockaddr*)&TcpClientAddr, &iSockAddrLen)) == SOCKET_ERROR){cerr << "\nFailed to accept the client TCP Socket\n"<< "error code: " << WSAGetLastError() << endl;return -1;}//TCP线程数达到上限,停止接受新的Clientif (TcpClientCount >= MAX_CLIENT){closesocket(TcpSocket);cout << "Connection from TCP client "<< inet_ntoa(TcpClientAddr.sin_addr) << ":" << ntohs(TcpClientAddr.sin_port) << " refused for max client num\n" << endl;continue;}cout << "Connection from TCP client "<< inet_ntoa(TcpClientAddr.sin_addr) << ":" << ntohs(TcpClientAddr.sin_port) << " accepted\n" << endl;TcpThreadParam Param;Param.socket = TcpSocket;Param.addr = TcpClientAddr;//创建TCP服务线程DWORD dwThreadId;CreateThread(NULL, 0, TcpServeThread, &Param, 0, &dwThreadId);InterlockedIncrement(&TcpClientCount);cout << "Current Number of TCP Clients: " << TcpClientCount << '\n' << endl;}closesocket(ListenSocket);WSACleanup();return 0;}//TCP服务线程DWORD WINAPI TcpServeThread(LPVOID lpParam){char ServerTCPBuf[MAX_BUF_SIZE];//获取线程参数SOCKET TcpSocket = ((TcpThreadParam*)lpParam)->socket;SOCKADDR_IN TcpClientAddr = ((TcpThreadParam*)lpParam)->addr;//输出提示信息cout<<"Thread: "<< GetCurrentThreadId() << " is serving client from " <<inet_ntoa(TcpClientAddr.sin_addr) << ":"<< ntohs(TcpClientAddr.sin_port) << endl << endl;//发送端口号+"START"sprintf(ServerTCPBuf, "%5d%s", UDPSrvPort, START_CMD);send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0);cout << "Waiting for command from Client(s)..." << endl << endl;int TCPBytesReceived;time_t CurSysTime;while (TRUE){//读取client发来的请求命令: "GET CUR TIME"memset(ServerTCPBuf, '\0', sizeof(ServerTCPBuf));TCPBytesReceived = recv(TcpSocket, ServerTCPBuf, sizeof(ServerTCPBuf), 0);//TCPBytesReceived值为0表示client端已正常关闭连接//TCPBytesRecieved值为SOCKET_ERROR则表示socket的状态不正常,无法继续数据通讯//两种情况下都表明本线程的任务已结束,需要退出if (TCPBytesReceived == 0 || TCPBytesReceived == SOCKET_ERROR){cout << "Client from " << inet_ntoa(TcpClientAddr.sin_addr) << ":" << ntohs(TcpClientAddr.sin_port) << " disconnected. Thread: " << GetCurrentThreadId() <<" is ending" << endl << endl;break;}//检查收到的字符串是否为命令:"GET CUR TIME"if (strcmp(ServerTCPBuf, GETCURTIME_CMD) != 0){cout << "Unknowm command from Client " << inet_ntoa(TcpClientAddr.sin_addr) << endl << endl;continue;}cout << "Request for Current time from client " <<inet_ntoa(TcpClientAddr.sin_addr) << ":" << ntohs(TcpClientAddr.sin_port) << " by TCP" << endl << endl;//获取系统时间并发送给clienttime(&CurSysTime);memset(ServerTCPBuf, '\0', sizeof(ServerTCPBuf));strftime(ServerTCPBuf, sizeof(ServerTCPBuf), "%Y-%m-%d %H:%M:%S",localtime(&CurSysTime));send(TcpSocket, ServerTCPBuf, strlen(ServerTCPBuf), 0);cout << "Server Current Time: " << ServerTCPBuf << '\n' << endl;}InterlockedDecrement(&TcpClientCount);closesocket(TcpSocket);return 0;}//UDP服务器线程DWORD WINAPI UdpServer(LPVOID lpParam){char ServerUDPBuf[MAX_BUF_SIZE]; //UDP BufferSOCKADDR_IN UDPClientAddr; //存储Client的地址信息//创建UDP server socketSOCKET UDPSrvSocket = socket(AF_INET, SOCK_DGRAM, 0);//获取本机名char hostname[256];gethostname(hostname, sizeof(hostname));//获取本地IP地址hostent *pHostent = gethostbyname(hostname);//填充本地UDP Socket地址结构SOCKADDR_IN UDPSrvAddr;memset(&UDPSrvAddr, 0, sizeof(SOCKADDR_IN));UDPSrvAddr.sin_family = AF_INET;UDPSrvAddr.sin_port = htons(UDPSrvPort);UDPSrvAddr.sin_addr = *(in_addr*)pHostent->h_addr_list[0];//绑定UDP端口if (bind(UDPSrvSocket, (sockaddr*)&UDPSrvAddr, sizeof(UDPSrvAddr)) == SOCKET_ERROR ) {cerr << "bind() failed for UDPSrvSocket\n"<< "error code: " << WSAGetLastError() << endl;return -1;}cout<<"UDP Server Started On UDP Port: " << UDPSrvPort << endl << endl;while (TRUE){memset(ServerUDPBuf, '\0', sizeof(ServerUDPBuf));//接收UDP请求int iSockAddrLen = sizeof(sockaddr);if ((recvfrom(UDPSrvSocket, ServerUDPBuf, sizeof(ServerUDPBuf), 0,(sockaddr*)&UDPClientAddr, &iSockAddrLen)) == SOCKET_ERROR){cerr << "recvfrom() failed for UDPSrvSocket\n"<< "error code: " << WSAGetLastError() << endl;continue;}cout << "Client Command: Echo\n\n";cout << "\"" << ServerUDPBuf<< "\"" << " received from " <<inet_ntoa(UDPClientAddr.sin_addr) << ":" << ntohs(UDPClientAddr.sin_port) << " by UDP" << endl << endl;//ECHOiSockAddrLen = sizeof(sockaddr);if ((sendto(UDPSrvSocket, ServerUDPBuf, strlen(ServerUDPBuf), 0,(sockaddr*)&UDPClientAddr, iSockAddrLen)) == SOCKET_ERROR ){cerr << "sendto() failed for UDPSrvSocket\n"<< "error code: " << WSAGetLastError() << endl;continue;}cout << "Echo " << "\"" << ServerUDPBuf << "\"" << " to clinet " <<inet_ntoa(UDPClientAddr.sin_addr) << ":" <<ntohs(UDPClientAddr.sin_port) << " by UDP" << endl << endl;}return 0;}client.exe#include"stdafx.h"#include"WinSock2.h"#include"iostream.h "#include"stdio.h"#pragma comment (lib,"Ws2_32.lib")#define MAX_BUF_SIZE 65535char ClientBuf[MAX_BUF_SIZE];const char START_CMD[] = "START";const char GETCURTIME_CMD[] = "GET CUR TIME";//输出用户选择界面void UserPrompt(){cout << "Input the corresponding Num to select what you want the program to do"<< endl << endl<< "\t1. Get current time(TCP)" << endl<< "\t2. Echo Mode(UDP)" << endl<< "\t3. Exit the program" << endl << endl<< "Enter Your choice: ";}int main(int argc, char* argv[]){unsigned short ServerUDPPort;SOCKET cTCPSocket,cUDPSocket;WSADATA wsadata;SOCKADDR_IN TCPServer,UDPServer,RecvFrom;int RecvFromLength=sizeof(RecvFrom);char UserChoice;char portnum[5];unsigned long BytesReceived,BytesSent;int RetValue;//检查命令行参数if (argc != 3){cout<<"Worng format!"<<endl<<"Correct usage: Client.exe <TCP Server IP> <TCP Server Port>"<<endl;return 1;}u_long ServerIP = inet_addr(argv[1]);u_short ServerTCPPort = (u_short)atoi(argv[2]);//初始化winsock库if( ( RetValue=WSAStartup(MAKEWORD(2,2),&wsadata) ) !=0 ){printf("WSAStartup() failed with error %d\n", RetValue);return 2;}//创建TCP Socketif( (cTCPSocket=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED) )==INVALID_SOCKET){printf("WSASocket() for cTCPSocket failed with error %d\n" ,WSAGetLastError() );return 3;}//创建UDP Socketif( (cUDPSocket=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_OVERLAPPED) )==INVALID_SOCKET){printf("WSASocket() for cUDPSocket failed with error %d\n" ,WSAGetLastError() );return 4;}TCPServer.sin_family=AF_INET;TCPServer.sin_port=htons(ServerTCPPort);TCPServer.sin_addr.S_un.S_addr=ServerIP;//通过TCP Socket连接serverif ((RetValue=WSAConnect(cTCPSocket,(sockaddr*)&TCPServer,sizeof(TCPServer),NULL,NULL,NULL,NULL) )==SOCKET_ERROR){printf("WSAConnect() failed for cTCPSocket with error %d\n",WSAGetLastError() );printf("Can't connect to server.\n");return 5;}//与server建立连接后读取Server发送过来的Server UDP端口和"START"BytesReceived=recv(cTCPSocket,ClientBuf,sizeof(ClientBuf),0 );if (BytesReceived == 0 || BytesReceived == SOCKET_ERROR){cout<<endl<<"Server refused the connection or recv failed"<<endl;return 6;}memcpy(portnum,ClientBuf,sizeof(portnum));ServerUDPPort=(u_short)atoi(portnum);if (strcmp(START_CMD,ClientBuf+5)!=0){cout<<endl<<"Server did not return right beginning indicator"<<endl;return 6;}else{cout<<endl<<"OK, NOW the server is ready for your service!"<<endl<<endl;}UDPServer.sin_family=AF_INET;UDPServer.sin_port=htons(ServerUDPPort);UDPServer.sin_addr.S_un.S_addr=ServerIP;while(TRUE){//输出提示信息UserPrompt();cin>>UserChoice;switch(UserChoice){case'1'://通过TCP得到server的系统时间//发送命令memset(ClientBuf,'\0',sizeof(ClientBuf));sprintf(ClientBuf,"%s",GETCURTIME_CMD);if((BytesSent=send(cTCPSocket,ClientBuf,strlen(ClientBuf),0) )==SOCKET_ERROR){printf("send() failed for cTCPSocket witherror %d\n",WSAGetLastError() );printf("Can not send command to server by TCP.Maybe Server is down.\n");return 7;}//读取server发来的系统时间并显示memset(ClientBuf,'\0',sizeof(ClientBuf) );if((BytesReceived=recv(cTCPSocket,ClientBuf,sizeof(ClientBuf),0) )==SOCKET_ERROR) {printf("recv() failed for cTCPSocket witherror %d\n",WSAGetLastError() );printf("Can not get server current systime.Maybe Maybe Server is down.\n");return 8;}cout<<"Server Current Time: "<<ClientBuf<<endl<<endl;break;case'2': //通过UDP实现ECHO//提示用户输入文本memset(ClientBuf,'\0',sizeof(ClientBuf) );cout<<"请输入任意文本信息,按回车键后将发送至Server."<<endl;gets(ClientBuf);//发送文本if ((BytesSent=sendto(cUDPSocket,ClientBuf,strlen(ClientBuf),0,(sockaddr *)&UDPServer,sizeof(UDPServer) ) ) ==SOCKET_ERROR){printf("sendto() failed for cUDPSocket witherror %d\n",WSAGetLastError() );printf("Can not send message by UDP.Maybe Server is down.\n");return 9;}//读取ECHOmemset(ClientBuf,'\0',sizeof(ClientBuf) );if((BytesReceived=recvfrom(cUDPSocket,ClientBuf,sizeof(ClientBuf),0,(sockaddr*)&RecvFrom, &RecvFromLength ) ) ==SOCKET_ERROR){printf("recvfrom () failed for cUDPSocket witherror %d\n",WSAGetLastError() );printf("Can't get Echo Reply from server by UDP.Maybe Server is down.\n");return 10;}//检查ECHO是否来自Serverif(UDPServer.sin_addr.S_un.S_addr==RecvFrom.sin_addr.S_un.S_addr&&UDPServer.sin_port==RecvFrom.sin_port){cout<<"Get Echo From Server: "<<ClientBuf<<endl<<endl;}else{cout<<"NO Echo From Server"<<endl;}break;case'3': //释放资源,退出程序closesocket(cTCPSocket);closesocket(cUDPSocket);WSACleanup();cout<<"program exit"<<endl;return 10;default:cout<<"Wrong choice ,should be 1,2 or 3"<<endl;}}return 11;}五、实验数据(现象)处理分析。
TCP_UDP通信过程学习及实验报告[五篇]第一篇:TCP_UDP通信过程学习及实验报告1.当两台计算机分别和中继器、二层交换机、三层交换、路由器相连时,请分别画出计算机与交换设备五层参考模型;计算机A应用层计算机B应用层传输层传输层网络层网络层数据链路层数据链路层中继器物理层物理层物理层计算机A应用层计算机B应用层传输层传输层网络层二层交换机数据链路层网络层数据链路层数据链路层物理层物理层物理层计算机A应用层计算机B应用层传输层三层交换机网络层传输层网络层网络层数据链路层数据链路层数据链路层物理层物理层物理层计算机A应用层计算机B应用层传输层路由器网络层传输层网络层网络层数据链路层数据链路层数据链路层物理层物理层物理层2.学习SOCKET编程,写出TCP、UDP通信流程;将实例程序两个同学一组,实现两台计算机之间通信。
并写出学习报告;(a)TCP通信流程准备阶段:服务器程序首先进行初始化操作:(1)调用socket创建一个套接字(2)函数bind将这个套接字与服务器公认地址绑定在一起(3)函数listen将这个套接字转换成倾听套接字(listening socket)(4)调用函数accept来接受客户机的请求。
客户机程序初始化操作:(1)客户机调用函数socket创建一个套接字(2)调用函数connect 来与服务器建立连接。
连接建立之后,客户机与服务器通过读(read())、写(write())套接字来进行通信。
如下图:服务器端SocketTCP通信流程客户端bindSocketListenconnectwritesendsendwritecloseclose(b)UDP通信流程准备阶段:服务器程序首先进行初始化操作:(1)调用socket创建一个套接字(2)函数bind将这个套接字与服务器公认地址绑定在一起客户机程序初始化操作:(1)客户机调用函数socket创建一个套接字客户机与服务器通过读(sendto())、写(recvfrom())套接字来进行通信。
第1页 共8页 实验报告 学院(系)名称:计算机科学与工程学院 姓名 学号 专业 计算机
班级 实验 项目 实验二:基于TCP/UDP的Socket编程 课程名称 计算机网络原理 课程 代码 0662013
实验时间 2019年04月28日 5-6节 2019年04月30日 3-4节 实验 地点 7-219 考核标 准
实验准备(实验目的/工具熟悉情况)10分 实验过程(实验方案可行性及步骤完整性)40分 实验报告(实验内容丰富度与格式清晰度) 30分 实验结果(结论正
确性以及分析合理性)20分 成绩
教师签字: 考核内容 评价实验目的是否明确,实验工具是否清晰了解以及熟悉情况 ○可行,完整 ○可行,不完整 ○不可行,不完整 ○丰富,清晰 ○较丰富,较清晰 ○丰富,不清晰 ○不丰富,不清晰 ○结论正确,分析合理 ○结论正确,分析不充分
○结论不正确,分析不合理 第2页 共8页
1. 实验目的 熟悉和掌握socket编程的基本理论和方法。掌握基于TCP和UDP的工作原理以及Socket编程的一般方法,能够编写简单的网络应用程序。
2. 实验工具 eclipse
3. 实验方案 利用Java或C++语言,分别基于TCP和UDP编写一个简单的Client/Server网络应用程序。要求实现客户向服务器传输任意一个字符串,服务器将收到的字符串变换成大写后传回客户。 修改上述程序,实现服务器根据客户请求,将服务器端指定的文件可靠地传输给客户。如果服务器没有指定的文件,服务器将给客户返回一个信息,通知客户其请求文件不存在。
4. 实验步骤 实现将字符串变换成大写传回给客户 Tcpcilent
package uppercase; import java.io.*; import java.net.*;
public class TCPClient { public static void main(String argv[]) throws Exception { String HOST = "0.0.0.0"; String sentence; String modifiedSentence; BufferedReader infromUser = new BufferedReader(new InputStreamReader(System.in)); Socket clientSocket = new Socket(HOST, 1234); DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream()); BufferedReader infromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); sentence = infromUser.readLine(); outToServer.writeBytes(sentence + '\n'); modifiedSentence = infromServer.readLine(); System.out.println("FROM SERVER:" + modifiedSentence); clientSocket.close(); } } 第3页 共8页
Tcpsever: package uppercase; import java.io.*; import java.net.*;
class TCPServer{ public static void main(String argv[]) throws Exception { String clientSentence; String capitalizedSentence; ServerSocket welcomeSocket = new ServerSocket(1234); while(true) { Socket connectionSocket = welcomeSocket.accept(); BufferedReader infromClient = new BufferedReader(new InputStreamReader(connectionSocket. getInputStream())); DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream()); clientSentence = infromClient. readLine(); capitalizedSentence = clientSentence.toUpperCase() + '\n'; outToClient.writeBytes(capitalizedSentence); } } }
用udp完成字符串大写 Udpsever:
package uppercase; import java.io.*; import java.net.*; class UDPServer { 第4页 共8页
public static void main(String args[]) throws Exception { DatagramSocket serverSocket = new DatagramSocket(1234); byte[] receiveData = new byte[1024]; byte[] sendData = new byte[1024]; while(true) { DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); serverSocket.receive(receivePacket); String sentence = new String(receivePacket.getData()); InetAddress IPAddress = receivePacket.getAddress(); int port = receivePacket.getPort(); String capitalizedSentence = sentence.toUpperCase(); sendData = capitalizedSentence.getBytes(); DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port); serverSocket.send(sendPacket); } } }
Udpclient package uppercase; import java.io.*; import java.net.*;
class UDPClient { public static void main(String args[]) throws Exception { String HOST = "127.0.0.1"; BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in)); DatagramSocket clientSocket = new DatagramSocket(); InetAddress IPAddress = InetAddress.getByName(HOST); byte[] sendData = new byte[1024]; byte[] receiveData = new byte[1024]; String sentence = inFromUser.readLine(); sendData = sentence.getBytes(); DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 1234); 第5页 共8页
clientSocket.send(sendPacket); DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); clientSocket.receive(receivePacket); String modifiedSentence = new String(receivePacket.getData()); System.out.println("FROM SERVER:" + modifiedSentence); clientSocket.close(); } }
用tcp传输文件 package uppercase; import java.io.*; import java.net.Socket;
class TCPFileClient { public static void main(String argv[]) throws Exception { String HOST = "0.0.0.0"; String filePath = "D:/bn/"; BufferedReader infromUser = new BufferedReader(new InputStreamReader(System.in)); String fileName = infromUser.readLine(); BufferedWriter bWriter = new BufferedWriter(new FileWriter(filePath + fileName)); Socket clientSocket = new Socket(HOST, 8810); DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());