实验07-TCP_IP+Socket编程
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《计算机网络》实验报告
实验序号:07 实验项目名称:TCP_IP Socket编程
学号姓名专业、班
实验地点实1-514 指导教师实验时间2013-11-26
一、实验目的及要求
1、通过对路由器安装与配置实验,加深对相关网络设备工作原理理解,掌握其常见产品的安装与配置方法,为将来从事网络工程建设打下基础。
2、通过实验,掌握路由器的基本参数配置、网络接口配置和路由协议配置,掌握静态路由的配置方法。
二、实验设备(环境)及要求
计算机;学生不许把食物带到机房吃;不许上网做与实验无关的内容;不许同学之间聊天;保持实验室安静卫生。
下课把键盘,座椅放回原处。
三、实验内容与步骤
1.分别编写基于TCP的socket程序服务端和客户端,要求客户端能发送消息到服务端,服务端再把此消息返回给客户端。
服务端:
(1)打开vc++6.0,File-》new-》Projects-》Win32 Console Application,输入Project name,例如SimpleTCP_s,选择location后单击OK,选择simple application,单击ok。
(2)打开SimpleTCP_s.cpp,输入如下内容:
#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h> //WINSOCK.H(这个是WINSOCK API的头文件,WIN2K以上支持WINSOCK2,所以
//可以用WINSOCK2.H);
#pragma comment(lib, "WS2_32.lib")//Ws2_32.lib(WINSOCK API连接库文件).
#define BUF_SIZE 1024
int main(int argc, char* argv[])
{
WSADA TA wsaData;
SOCKET socketL; // socket for listening
SOCKET socketC; // socket for Communication
SOCKADDR_IN serverAddr;
int nRet = -1;
char recvbuf[BUF_SIZE];
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
printf("WSAStartup failed!\n");
return 1;
}
socketL = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(5678);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(socketL, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
listen(socketL, 5);
socketC = accept(socketL, NULL, NULL);
if (socketC != INV ALID_SOCKET)
{
nRet = recv(socketC, recvbuf, sizeof(recvbuf), 0);
if (nRet > 0)
printf("%s ", recvbuf);
}
closesocket(socketC);
closesocket(socketL);
WSACleanup();
printf("请按回车键关闭");
getchar();
return 0;
}
(3)编译工程
客户端:
(1)和服务端一样操作,建立SimpleTCP_c工程。
(2)打开SimpleTCP_c.cpp,输入如下内容:
#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "WS2_32.lib")
#define BUF_SIZE 1024
int main(int argc, char* argv[])
{
WSADA TA wsaData;
SOCKADDR_IN serverAddr;
SOCKET socketC;
char sendbuf[BUF_SIZE] = "Hello TCP World!";
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
{
printf("WSAStartup failed!\n");
return 1;
}
socketC = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(5678);
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(socketC, (SOCKADDR*)&serverAddr, sizeof(serverAddr));
send(socketC, sendbuf,sizeof(sendbuf), 0);
closesocket(socketC);
WSACleanup();
printf("请按回车键关闭");
getchar();
return 0;
}
(3)编译工程
分别运行服务端SimpleTCP_s.exe和客户端SimpleTCP_c.exe,则在服务端显示"Hello TCP World!"。
结果:
2.在上述程序的基础上,实现客户端和服务端间的简易聊天功能,即服务端和客户端能依次从键盘输入文字信息并发送(要求在两台不同的电脑上进行)。
服务器:
InitSock.h:
#include <winsock2.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#pragma comment(lib,"WS2_32") // 链接到WS2_32.lib
class CInitSock
{
public:
CInitSock(BYTE minorVer = 2, BYTE majorVer = 2)
{
// 初始化WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer, majorVer);
if(::WSAStartup(sockVersion, &wsaData) != 0)
{
exit(0);
}
}
~CInitSock()
{
::WSACleanup();
}
};
Main:
#include "InitSock.h"
#include <stdio.h>
#include <iostream.h>
CInitSock initSock; // 初始化Winsock库
int main()
{
// 创建套节字
SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sListen == INVALID_SOCKET)
{
printf("Failed socket() \n");
return 0;
}
// 填充sockaddr_in结构
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(4567);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
// 绑定这个套节字到一个本地地址
if(::bind(sListen, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("Failed bind() \n");
return 0;
}
// 进入监听模式
if(::listen(sListen, 2) == SOCKET_ERROR)
{
printf("Failed listen() \n");
return 0;
}
// 循环接受客户的连接请求
sockaddr_in remoteAddr;
int nAddrLen = sizeof(remoteAddr);
SOCKET sClient = 0;
char szText[] = " TCP Server Demo! \r\n";
while(sClient==0)
{
// 接受一个新连接
sClient = ::accept(sListen, (SOCKADDR*)&remoteAddr, &nAddrLen);
if(sClient == INVALID_SOCKET)
{
printf("Failed accept()");
}
printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr)); continue ;
}
while(TRUE)
{
// 向客户端发送数据
gets(szText) ;
::send(sClient, szText, strlen(szText), 0);
// 从客户端接收数据
char buff[256] ;
int nRecv = ::recv(sClient, buff, 256, 0);
if(nRecv > 0)
{
buff[nRecv] = '\0';
printf(" 接收到数据:%s\n", buff);
}
}
// 关闭同客户端的连接
::closesocket(sClient);
// 关闭监听套节字
::closesocket(sListen);
return 0;
}
客户端;
InitSock.h:
#include <winsock2.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#pragma comment(lib,"WS2_32") // 链接到WS2_32.lib class CInitSock
{
public:
CInitSock(BYTE minorVer = 2, BYTE majorVer = 2)
{
// 初始化WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer, majorVer); if(::WSAStartup(sockVersion, &wsaData) != 0)
{
exit(0);
}
}
~CInitSock()
{
::WSACleanup();
}
};
Main:
#include "InitSock.h"
#include <stdio.h>
#include <iostream.h>
CInitSock initSock; // 初始化Winsock库
int main()
{
SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s == INVALID_SOCKET)
{
printf(" Failed socket() \n");
return 0;
}
// 也可以在这里调用bind函数绑定一个本地地址
// 否则系统将会自动安排
// 填写远程地址信息
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(4567);
// 注意,这里要填写服务器程序(TCPServer程序)所在机器的IP地址
// 如果你的计算机没有联网,直接使用127.0.0.1即可
servAddr.sin_addr.S_un.S_addr = inet_addr("172.16.192.111"); if(::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1) {
printf(" Failed connect() \n");
return 0;
}
char buff[256];
char szText[256] ;
while(TRUE)
{
//从服务器端接收数据
int nRecv = ::recv(s, buff, 256, 0);
if(nRecv > 0)
{
buff[nRecv] = '\0';
printf("接收到数据:%s\n", buff);
}
// 向服务器端发送数据
cin>>szText ;
szText[255] = '\0';
::send(s, szText, strlen(szText), 0) ;
}
::closesocket(s);
return 0;
}
结果:
服务端:
客户端:
(3)改用UDP实现此程序的功能。
InitSock.h:
#include <winsock2.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#pragma comment(lib,"WS2_32") // 链接到WS2_32.lib class CInitSock
{
public:
CInitSock(BYTE minorVer = 2, BYTE majorVer = 2) {
// 初始化WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer, majorVer);
if(::WSAStartup(sockVersion, &wsaData) != 0)
{
exit(0);
}
}
~CInitSock()
{
::WSACleanup();
}
};
StdAfx.cpp:
/*
《使用说明》
0.运行程序前请查看是否将initsock.h
文件引入到项目中。
1.首先修改聊天对方的IP地址
2.运行程序:如配置正确另一方会收到相关连接信息。
3.输入消息:在每次输入完欲发送的消息后,需要连续敲击两次回车。
4.本程序有诸多缺陷:对用户输入的消息不能即时回显到控制台,
需要在敲击两次回车后回显到屏幕。
*/
#include "stdafx.h"
#include <iostream>
#include <stdlib.h>
#include <STDIO.H>
#include <windows.h>
#include "InitSock.h"
using namespace std;
CInitSock initSock; // 初始化Winsock库
DWORD receiverMark ; //接收消息者线程标识符
DWORD senderMark ;//发送者线程标识符
/**
*定义信号量
*/
DWORD WINAPI Receiver(LPVOID) ;
DWORD WINAPI Sender(LPVOID) ;
// 接收数据
char buff[1024];
sockaddr_in addr;
int nLen = sizeof(addr);
SOCKET s ;
int main(int argc, char *argv[])
{
// 创建套节字
s= ::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //u_long iMode = 1;
//ioctlsocket(s, FIONBIO, &iMode);
if(s == INVALID_SOCKET)
{
printf("Failed socket() \n");
return 0;
}
// 填充sockaddr_in结构
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(4567);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
addr.sin_family = AF_INET;
addr.sin_port = htons(4567);
// 注意,这里要填写服务器程序所在机器的IP地址
// 如果你的计算机没有联网,直接使用127.0.0.1即可
addr.sin_addr.S_un.S_addr = inet_addr("172.16.192.117");
// 绑定这个套节字到一个本地地址
if(::bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("Failed bind() \n");
return 0;
}
// 发送数据
char szText[] = "PC请求连接... \r\n";
::sendto(s, szText, strlen(szText), 0, (sockaddr*)&addr,sizeof(addr));
CreateThread(NULL,0,Receiver,NULL,0,&receiverMark);
CreateThread(NULL,0,Sender,NULL,0,&senderMark);
bool isContinue = true ;
while(isContinue)
{
if(getche()==96){ //按~后终止程序运行
isContinue = false;
}
}
system("PAUSE");
return 0;
}
/**
*接收者
*/
DWORD WINAPI Receiver(LPVOID lpParam )
{
while(1)
{
int nRecv = ::recvfrom(s, buff, 1024, 0, (sockaddr*)&addr,&nLen);
if(nRecv > 0)
{
buff[nRecv] = '\0';
printf(" Received data(%s):%s\n", ::inet_ntoa(addr.sin_addr), buff);
}
}
return 0;
}
/**
*发送者
*/
DWORD WINAPI Sender(LPVOID lpPara)
{
while(1)
{
cout<<"Input your message: " ;
// 发送数据
char text[256] ;
cin>>text ;
text[255] = '\0' ;
cout<<text<<endl ;
::sendto(s, text, strlen(text), 0, (sockaddr*)&addr, sizeof(addr));
}
return 0;
}
结果:
(4)使用netstat命令观察程序运行前后的端口变化情况并记录下来。
运行前:
运行服务端后:
运行客户端后:
四、实验心得体会
成绩五、教师评语
签名:
日期:。