网络实践课程设计报告

计算机网络实践设计报告

学院: 计算机 班级: 成教2012业余 教师: 李领治 学号: 姓名: 成绩: 实验目的:

掌握Winsock2.0套接字编程技术的基本方法。

实验要求:

运用TCP/IP Winsock2.0套接字编程技术,使用VC编写一个面向连接通信的服务端程序与客户端程序,服务器先与端口3000绑定,然后等待客户连接,连接成功后就可与客户端互相收、发信息。交互中,通信任一方只要发送 bye, 通信过程便自动结束。 实验源程序:

服务器程序:

#pragma comment (lib, "Ws2_32.lib") //Winsock 2 函数库

//-------------------------------------------------------

#include <conio.h>

#include <stdio.h>

#include <winsock2.h> //Winsock 2 函数头文件 //-------------------------------------------------------

bool InitSocket();

int main(int, char**)

{

struct sockaddr addr;

int len;

bool over;

char msg[255];

SOCKET sock, sersock;

if( !InitSocket() ) return 0;

//加载初始化 Winsock 2 动态链接库 Ws2_32.dll

sock = socket( AF_INET,SOCK_STREAM,0 );

//创建监听的流套接口

if( sock==INVALID_SOCKET ){ //不能创建,返回

printf("不能创建Socket!\n");

getch();

WSACleanup( ); //卸载Winsock 2动态链接库Ws2_32.dll

return 0; }

//设置本服务器IP地址和端口号

((sockaddr_in*)&addr)->sin_family = AF_INET;

//AF_INET:使用Internet 协议

((sockaddr_in*)&addr)->sin_port = htons(3000);

//服务器端口号3000

((sockaddr_in*)&addr)->sin_addr.s_addr = inet_addr("127.1.1.1"); //主机地址

//把套接口与地址绑定

bind(sock,&addr,sizeof(addr));

//服务进程准备接收套接口上的连接请求

listen(sock,1); //监听方式,准备接收连接请求:1--允许等待队列中的连接请求1个

//接受网络连接,生成新的套接口sersock标识这一连接

printf("等待客户连接!\n");

len = sizeof(addr);

sersock = accept( sock,&addr,&len );

//从等待队列中检取连接请求,如队列空则进程阻塞等待;

//如不空,则接受客户连接,使用返回连接套接口sersock与该客户连接。 //原套接口sock可继续监听其它客户请求。

if(sersock==INVALID_SOCKET) { //若套接口sersock 出错

DWORD err = WSAGetLastError();

char txt[100];

sprintf(txt,"error when accept!---errno:%d",err);

printf(txt);

getch();

closesocket(sock); //关闭监听套接口sock

WSACleanup( ); //卸载Winsock 2动态链接库Ws2_32.dll

return 0;

}

printf("有客户连接!\n输入bye通信结束\n");

over = false; //状态设置为未结束

//与客户交互会话,直至任一方打入bye后退出循环

do{

printf("\n等待对方用户输入信息......");

len = recv ( sersock,msg,200,0 ); //接收对方信息

printf("\n对方输入:%s",msg); //显示对方信息

if( strcmp(msg,"bye")==0 ) //若对方信息为bye就结束通信

break;

printf("\n本方回答:");

gets(msg); //键入本方信息

if( strcmp(msg,"bye")==0 ) over = true;

//若本方发出bye就结束通信 send ( sersock,msg,strlen(msg)+1,0 );

//将本方键入信息发给对方 } while( !over );

closesocket(sersock); //关闭连接套接口

closesocket(sock); //关闭监听套接口

printf("\n\n会话结束,按任一键返回\n");

getch();

WSACleanup( ); //卸载 Winsock 2 动态链接库Ws2_32.dll

return 0;

}

//----------------------------------------------------------------------

//下述函数加载初始化Winsock 2 动态链接库 Ws2_32.dll

bool InitSocket()

{

WORD wVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD( 2, 0 ); //Wiinsock2.0版

err = WSAStartup( wVersionRequested, &wsaData ); //加载

if ( err != 0 ) { //没有Winsock 2 动态链接库 Ws2_32.dll

printf("没有Windows Socket动态库!\n");

getch();

return false;

}

if ( LOBYTE( wsaData.wVersion ) != 2 || //不是Winsock 2.0

HIBYTE( wsaData.wVersion ) != 0 ) {

printf("需要Windows Socket 2!\n");

getch();

WSACleanup( ); //卸载 Winsock 动态链接库

return false;

}

return true;

}

客户端程序:#pragma comment (lib, "Ws2_32.lib") //Winsock 2 函数库 //------------------------------------------------------------------------ #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> //Winsock 2 函数头文件 //------------------------------------------------------------------------- bool InitSocket(); int main(int , char**) { int type; SOCKET sock; struct sockaddr addr; int len,portno; int err; char msg[255]; bool over; if( !InitSocket() ) return 0; //加载初始化 Winsock 2 动态链接库 Ws2_32.dll type = SOCK_STREAM; sock = socket( AF_INET,type,0 ); //创建客户端流套接口 if( sock==INVALID_SOCKET ){ //不能创建,返回 printf("不能创建Socket!"); getch(); WSACleanup( ); //卸载Winsock 2动态链接库Ws2_32.dll return 0; } // 以下输入对方服务器IP地址 ((sockaddr_in*)&addr)->sin_family = AF_INET; // Internet 协议 printf("输入服务器地址(x.x.x.x):"); gets(msg); ((sockaddr_in*)&addr)->sin_addr.s_addr = inet_addr(msg); // inet_addr()将点分十进制IP地址串转换为u_long类型 // 以下输入对方服务器端口号 printf("输入对方服务器端口号(3000):"); gets(msg); if(msg[0]==0x00) portno=3000; //如果直接回车,就采用默认端口号3000 else portno=atoi(msg); ((sockaddr_in*)&addr)->sin_port = htons( portno ); // htons():从短整数的主机字节顺序转换为网络字节顺序 // 以下与对方服务器连接 // 在使用面向连接协议 (TCP)时,必须与服务器连接成功后, // 才可通信;另外,若使用无连接的协议(UDP) ,则可以直 // 接向对方发数据、无需连接, 但面向连接收、发数据时用 // 的send()和recv()要换成无连接用的函数 sendto()和recvfrom() printf("与服务器连接...!"); len = sizeof(addr); err = connect( sock,(sockaddr*)&addr,len ); //连接 if( err==SOCKET_ERROR ){ //若连接失败

printf("连接失败!"); getch(); WSACleanup( ); //卸载Winsock 2动态链接库Ws2_32.dll return 0; } printf("成功连接到服务器!\n若输入bye则通信结束\n"); over = false; //状态设置为未结束 // 以下为客户与服务器会话交互,直至输入或收到bye,则 // 退出循环,结束 do{ printf("\n\n本方输入:"); gets(msg); if( strcmp(msg,"bye")==0 ) over = true; //输入"bye"则结束通信 send ( sock,msg,strlen(msg)+1,0); //发送信息 if(over) break; printf("等待服务器响应......\n"); len = recv ( sock,msg,200,0 ); //接收信息,接收缓冲区长200 msg[len]=0; //在接收串变量尾添结束符0 if( strcmp(msg,"bye")==0 ) over = true; //收到"bye"则结束通信 printf("对方回答:"); printf(msg); //显示接收信息 }while( !over ); //以下关闭套接口,卸载Winsock 2动态链接库 closesocket(sock); //关闭客户套接口 printf("\n会话结束,按任一键返回\n"); getch(); WSACleanup( ); //卸载Winsock 2动态链接库Ws2_32.dll return 0; } //--------------------------------------------------------------- //下述函数加载初始化Winsock 2 动态链接库 Ws2_32.dll bool InitSocket() { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD( 2, 0 ); //Wiinsock2.0版 err = WSAStartup( wVersionRequested, &wsaData ); //加载 if ( err != 0 ) { //没有Winsock 2 动态链接库 Ws2_32.dll printf("没有Windows Socket动态库!\n"); getch(); return false; } if ( LOBYTE( wsaData.wVersion ) != 2 || //不是Winsock 2.0 HIBYTE( wsaData.wVersion ) != 0 ) { printf("需要Windows Socket 2!\n"); getch(); WSACleanup( ); //卸载 Winsock 动态链接库 return false; }

} return true;

 

第二篇:网络程序课程设计实验报告

网络程序课程设计实验报告

专业:08计算机网络

姓名:

学号:v2008410 指导老师:辜希武

1

一、 实验目的

1、了解应用层和运输层的作用及相关协议的工作原理和机制。

2、掌握SOCKET 编程的基本方法。

二、 实验环境

1、Windows 操作系统

2、 C、C++编程开发环境(Microsoft Visual C++ 6.0)

三、实验要求

1、 基于Socket 编程

2、 提交实验设计报告和源代码;实验设计报告包括程序流程

3、 基于自己的实验设计报告,通过实验课的上机试验,在C++编程环境下将源代码编译

四、实验内容

题目一:

编写一个简单的基于控制台的Client/Server 通信程序,学习了解socket 编程的基本方法。程序功能为: 客户端向服务器端发送字符串,服务器接受并显示在服务器端窗口上 客户端可以指定服务器的IP 地址和端口 服务器显示接受到的字符串时要同时显示发送该字符 串的客户端地址和端口号

题目二:

编写一个基于控制台的聊天室程序,程序功能为: 服务器端首先建立聊天室,可以自由选择端口号 客户端输入服务器端的IP 地址和端口,然后登录到聊天室 客户在控制台输入的信息发送到服务器端 服务器端收到某客户端发来的信息后首先显示在屏幕上,并转发到其他聊天室客户端,并在其他客户端的控制台 上显示,显示格式为:【客户端IP 地址】:信息 当某客户离开聊天室后服务器能感知并发消息给其他客户端

题目三:

编写邮件客户端,功能要求如下: 客户端可以指定收件人地址,邮件主题,邮件正文并发送邮

件 客户点可以打开一个邮箱并显示邮箱里的邮件列表 客户端可以将邮件列表里的邮件下载到本地并显示

五、程序设计说明

1、主要模块:由Server和Client组成。在Server这一端初始化winsock、创建会话socket、bind一个端口、设置等待链接状态、连接并生成会话、调用send和recv、关闭socket。

2、模块功能:

初始化winsock:完成一系列初始化的工作。

创建会话socket:所有的通信在建立之前都要建一个socket。

bind一个端口:成功创建了一个socket后,用bind函数将socket和主机地址绑定。

设置等待链接状态:对于服务器的程序,当申请到socket,并将通信对象指定为inaddr_any之后,就应该等待一个客户机的程序来要求连接,listen函数就是把一个socket设置为这个状态。

连接并生成会话:accept函数从等待连接的队列中取第一个连接请求,并且创建一个新的socket来负责与客户端会话。

2

调用send和recv:sendto一般用于无连接的socket发送数据报文,报文的接受者由to参数指定。Recvfrom一般用于通过无连接的socket接收数据报文,报文的发送者由from参数指定。

关闭socket:关闭指定的socket。

3、程序主要流程图:

网络程序课程设计实验报告

六、程序代码运行结果(部分源代码略)

1、服务器端执行结果

网络程序课程设计实验报告

网络程序课程设计实验报告

网络程序课程设计实验报告

网络程序课程设计实验报告

3

2、客户端执行结果

网络程序课程设计实验报告

3、开多个客户端,利用多线程实现

网络程序课程设计实验报告

网络程序课程设计实验报告

4、邮件客户端程序winsock源代码:

#pragma once

#include "EmailClient.h" #include "base64.h"

#include <iostream>

using namespace std;

void SendMail(){

Client client; if(client.Init() == EXIT_FAILURE) return; //设置发件人地址、收件人地址 string from = "cnbluesky@163.com"; string to ="cnbluesky@163.com"; string responseFromServer; string commandToServer; string username = "cnbluesky"; string password = "cnbluesky"; string encodedUserName; string encodedPassword; //设置邮件正文

4

string mailContent = "From: " + from + "\n" + "To: " + to + "\n" + "Subject: " + "Test" + "\n" + "\n" + "This is a test email!"; //得到主机名 string localHostName = client.GetLocalHostName(); //接受服务器的应答 responseFromServer = client.RecvMsg(); //显示来自服务器的应答 cout << "MailServer:" + responseFromServer; //准备发送到服务器的命令

//EHLO 主机名

cout << "Client:" + commandToServer; //发送命令 client.SendMsg(commandToServer); // Sleep(1000); //接受服务器的应答 size_t found; do{ responseFromServer = client.RecvMsg(); //显示来自服务器的应答 cout << "MailServer:" + responseFromServer; found = responseFromServer.find("250 "); commandToServer = "EHLO " + localHostName + "\r\n"; }while(found == string::npos); //准备发送到服务器的命令 commandToServer = string("AUTH LOGIN") + "\r\n"; cout << "Client:" + commandToServer; //发送命令 client.SendMsg(commandToServer); //显示来自服务器的应答 cout << "MailServer:" + responseFromServer; //将用户名和密码进行base64编码 encodedUserName encodedPassword = = base64_encode(reinterpret_cast<const base64_encode(reinterpret_cast<const unsigned unsigned char char //AUTH LOGIN //接收服务器的应答 responseFromServer = client.RecvMsg(); *>(username.c_str()),username.length()); *>(password.c_str()),password.length()); //准备发送到服务器的命令 commandToServer = encodedUserName + "\r\n"; cout << "Client:" + commandToServer; //发送命令 client.SendMsg(commandToServer); //用户名 5

//接收服务器的应答

responseFromServer = client.RecvMsg();

//显示来自服务器的应答

cout << "MailServer:" + responseFromServer;

//准备发送到服务器的命令

commandToServer = encodedPassword + "\r\n";

cout << "Client:" + commandToServer;

//发送命令

client.SendMsg(commandToServer); //密码

//接收服务器的应答

responseFromServer = client.RecvMsg();

//显示来自服务器的应答

cout << "MailServer:" + responseFromServer;

//准备发送到服务器的命令

commandToServer = "MAIL FROM: <" + from + ">" + "\r\n"; cout << "Client:" + commandToServer;

//发送命令

client.SendMsg(commandToServer); //MAIL FROM: <发送信箱> //接收服务器的应答

responseFromServer = client.RecvMsg();

//显示来自服务器的应答

cout << "MailServer:" + responseFromServer;

//准备发送到服务器的命令

commandToServer = "RCPT TO: <" + to + ">" + "\r\n";

cout << "Client:" + commandToServer;

//发送命令

client.SendMsg(commandToServer); //RCPT TO: <接收信箱> //接收服务器的应答

responseFromServer = client.RecvMsg();

//显示来自服务器的应答

cout << "MailServer:" + responseFromServer;

//准备发送到服务器的命令

commandToServer = string("DATA") + "\r\n";

cout << "Client:" + commandToServer;

//发送命令

client.SendMsg(commandToServer); //DATA

//接收服务器的应答

responseFromServer = client.RecvMsg();

//显示来自服务器的应答

cout << "MailServer:" + responseFromServer;

//准备发送邮件正文

commandToServer = mailContent + "\r\n";

6

}

网络程序课程设计实验报告

//发送命令 client.SendMsg(commandToServer); //邮件正文 commandToServer = string(".") + "\r\n"; client.SendMsg(commandToServer); client.SendMsg(commandToServer); //接收服务器的应答 responseFromServer = client.RecvMsg(); //显示来自服务器的应答 cout << "MailServer:" + responseFromServer; string input; do { cout << "\nPlease enter 'q' to quit:"; cin >> input; //结束标记"." commandToServer = string("QUIT") + "\r\n"; // QUIT }while(input != "q"); return;

七、实验心得:由于对编程的不熟悉,在编写代码的过程中问题很多,这样一份作业难度很大,不过

好的学习态度很重要。

7

相关推荐