计算机课实验三,成都信息工程学院计算机网络课程实验三
成都信息工程學院計算機網絡課程實驗三 本文關鍵詞:成都,計算機網絡,信息工程學院,課程,實驗
成都信息工程學院計算機網絡課程實驗三 本文簡介:計算機網絡實驗報告實驗三:編寫客戶服務器程序班級xxxxx姓名xxxxxxxxxxxxx學號xxxxxxxxx日期xxxxxxxx一、實驗目的:學習TCP/UDP協議套接字編程,深入理解客戶服務器程序的原理,以及端口作用等。二、實驗內容編寫客戶服務器程序,服務器運行后等待客戶連接,一旦收到客戶送來的
成都信息工程學院計算機網絡課程實驗三 本文內容:
計算機網絡
實驗報告
實驗三:編寫客戶服務器程序
班級
xxxxx
姓名
xxxxxxxxxxxxx
學號
xxxxxxxxx
日期
xxxxxxxx
一、
實驗目的:
學習TCP/UDP協議套接字編程,深入理解客戶服務器程序的原理,以及端口作用等。
二、
實驗內容
編寫客戶服務器程序,服務器運行后等待客戶連接,一旦收到客戶送來的信息,立即回送回去。
客戶機等待用戶輸入信息,然后發送給服務器。并接受服務器回送回來的信息。所有的信息均需顯示在屏幕上。
三、
程序實現設計方法
編寫客戶服務器程序,服務器運行后等待客戶連接,一旦收到客戶送來的信息,立即送回去。
客戶機等待用戶輸入信息,然后發送給服務器。并接受服務器回送回來的信息。所有的信息均需顯示在屏幕上。
可以每2個人一組,一個負責服務器端,一個負責客戶端。(自己協商使用udp還是tcp方式,端口號)
上機實驗過程:
1、啟動winXP,運行vc程序
2、新建一個文件,錄入編輯好的服務器程序或客戶程序
3、分別以server.c或client.c保存
4、打開build/compile菜單,系統會自動建立一個新的工程,然后完成編譯工作
5、打開project/settings.菜單,在對話框的link標簽下,找到project
options:編輯框,在其中添加“WS2_32.LIB”
6、打開build/build菜單,系統生成執行程序server.exe或client.exe
7、分別運行server.exe,client.exe,觀察兩個程序運行結果
四、
源程序
服務器端程序
/****************************************************Windows環境下使用VC編寫的TCP通信服務器端程序在編譯這個程序時,需要在工程設置項目--〉連接項目中添加如下兩項:
Ws2_32.lib和Winmm.lib否則編譯后鏈接生成可執行文件時會出錯!服務器程序在單機內的測試運行方法:
server
[監聽端口:缺省為9999]程序中的函數列表:int
InitSockets(void):
插口(套接字)初始化void
ServeAClient(LPVOID
lpv):為客戶提供服務的函數int
ServerLoop(SOCKET
sd_listen,int
isMultiTasking):
服務器循環函數,服務期間總是在這個函數中循環********************************************************/
#include
#include
#include
/*
由于Winsock目前有兩個版本:2.2和1.1,所以我們首先必須判斷系統所支持的Winsock版本,這就要靠WSAStartup函數了。
另外還有一個WSACleanup函數,這兩個函數是Winsock編程必須調用的,其中WSAStartup函數的功能是初始化Winsock
DLL,因為在Windows下,Socket是以DLL的形式實現的。1.1版本的DLL為Winsock.dll,而2.2版本的DLL則為Wsock32.dll,其中在2.2版本的系統中,對Winsock1.1函數的調用會由Wsock32.dll自動映射到Winsock.dll。WSAStartup函數的功能就是初始化DLL,其函數原型為:
int
WSAStartup
(WORD
wVersionRequested,LPWSADATA
lpWSAData);
其第一個參數為你所想需要的Winsock版本!低字節為主版本,高字節為副版本!由于目前Winsock有兩個版本:1.1和2.2,因此該參數可以是0x101或0x202;第2個參數是一個WSADATA結構,用于接收函數的返回信息!WSAStartup函數調用成功會返回0,否則返回非0值!
由于Win
95,WinNT4自帶的Winsock是1.1版本的,所以如果你的程序是基于Winsock2.2的,那很可能無法在上面運行。因此,如果你希望你寫的程序被所有Windows平臺支持的話,最好將其聲明成1.1版的,不過這樣將無法使用很多Winsock2.2才有的特性!至于WSACleanup的用法很簡單,用“WSACleanup();”就行了!另外,在DLL內部維持著一個計數器,只有第一次調用WSAStartup才真正裝載DLL,以后的調用只是簡單的增加計數器,而WSACleanup函數的功能則剛好相反,每調用一次使計數器減1,當計數器減到0時,DLL就從內存中被卸載!因此,你調用了多少次WSAStartup,就應相應的調用多少次的WSACleanup!/
int
InitSockets(void)
{
WSADATA
wsaData;
WORD
wVersionRequested;
int
err;
/*
Ask
for
Winsock
1.1
functionality/
wVersionRequested
=
MAKEWORD(
1,1
);
err
=
WSAStartup(
wVersionRequested,if
(
err
!=
0
)
{
printf(“Error
%d:
Winsock
not
available/n“,err);
return
1;
}
return
0;
}
#define
WSA_ERROR(x)
{
printf(“Error
%d:
%s/n“,/
WSAGetLastError(),x);
return
1;
}
int
ServerLoop(SOCKET
sd_listen,int
isMultiTasking);
main(int
argc,char*argv)
{
SOCKET
sd_listen;
int
err;
u_short
iPort;
struct
sockaddr_in
addr_srv;
struct
hostentptrHost;
iPort
=
(argc
>=
2)
?
atoi(argv[1])
:
9999;//從命令行中提取服務器監控的端口號,如果命令行沒有帶數字格式的端口號,則定為9999
InitSockets();//初始化套接字
/*
創建套接字有兩個函數,socket和WSASocket,前者是標準的Socket函數,而后者是微軟對Socket的擴展函數。socket函數有3個參數,第一個是指定通信發生的區域,在UNIX下有AF_UNIX、AF_INET、AF_NS等,而在Winsock1.1下只支持AF_INET,到了2.2則添了AF_IRDA(紅外線通信)、AF_ATM(異步網絡通信)、AF_NS、AF_IPX等;第2個參數是套接字的類型,在AF_INET地址族下,有SOCK_STREAM、SOCK_DGRAM、SOCK_RAW三種套接字類型。SOCK_STREAM也就是通常所說的TCP,而SOCK_DGRAM則是通常所說的UDP,而SOCK_RAW則是用于提供一些較低級的控制的;第3個參數依賴于第2個參數,用于指定套接字所用的特定協議,設為0表示使用默認的協議。socket函數調用成功返回一個套接字描述符,錯誤則返回SOCKET_ERROR。/
sd_listen
=
socket(PF_INET,SOCK_STREAM,0);
if
(sd_listen
==
INVALID_SOCKET)
{
printf(“Error:
out
of
socket
resources/n“);
return
1;
}
/*
接下來要為服務器端定義的這個監聽的socket指定一個地址及端口(Port),這樣客戶端才知道要連接哪一個地址的哪個端口,為此我們首先設置數據結構struct
sockaddr中的參數,隨之調用bind()函數將socket邦定在指定的端口和地址上,該函數調用成功返回0,否則返回SOCKET_ERROR。sockaddr_in結構的sin_addr.s_addr成員被設置為INADDR_ANY,意味著由操作系統給socket自動指定一個最有效的IP地址。/
addr_srv.sin_family
=
PF_INET;
addr_srv.sin_addr.s_addr
=
htonl(INADDR_ANY);
addr_srv.sin_port
=
htons(iPort);
err
=
bind(sd_listen,(const
struct
sockaddr)
if
(err
==
INVALID_SOCKET)
WSA_ERROR(“Error:
unable
to
bind
socket/n“)
/*
當服務器端的Socket對象綁定完成之后,服務器端必須通知操作系統為這個socket建立一個監聽隊列來接收客戶端的連接請求。listen()函數使服務器端的Socket
進入監聽狀態,并設定可以建立的最大連接數。該函數調用成功返回0,否則返回SOCKET_ERROR。/
err
=
listen(sd_listen,SOMAXCONN);
if
(err
==
INVALID_SOCKET)
WSA_ERROR(“Error:
listen
failed/n“)
//程序進入服務循環函數
ServerLoop(sd_listen,1);
printf(“Server
is
down/n“);
WSACleanup();
return
0;
}
/*
如果客戶端發來HELLO
SERVER,
那么服務器端將回送HELLO
CLIENT,
不符合的輸入,服務器端將沒有響應/
void
ServeAClient(LPVOID
lpv)
{
SOCKET
sd_accept
=
(SOCKET)
lpv;
const
charmsg
=
“HELLO
CLIENT“;
char
response[4096];
memset(response,0,sizeof(response));
recv(sd_accept,response,sizeof(response),0);
if
(strcmp(response,“HELLO
SERVER“))
{
printf(“Application:
client
not
using
expected
““protocol
%s/n“,response);
}
else
send
(sd_accept,msg,strlen(msg)+1,0);
closesocket(sd_accept);
}
#define
MAX_SERVED
3
//服務器端的循環函數,服務期間總是在這個函數中運行
int
ServerLoop(SOCKET
sd_listen,int
isMultiTasking)
{
SOCKET
sd_accept;
struct
sockaddr_in
addr_client;
int
err,nSize;
int
numServed
=
0;
HANDLE
handles[MAX_SERVED];
int
myID;
//主循環體,服務期間總是在這個結構內循環
while
(numServed
#include
int
InitSockets(void)
{
WSADATA
wsaData;
WORD
wVersionRequested;
int
err;
/*
Ask
for
Winsock
1.1
functionality/
wVersionRequested
=
MAKEWORD(
1,1
);
err
=
WSAStartup(
wVersionRequested,if
(
err
!=
0
)
{
printf(“Error
%d:
Winsock
not
available/n“,err);
return
1;
}
return
0;
}
#define
WSA_ERROR(x)
{
printf(“Error
%d:
%s/n“,/
WSAGetLastError(),x);
return
1;
}
//void
InitSockets(void);
main(int
argc,char*argv)
{
SOCKET
sd_client;
int
err;
u_short
iPort;
struct
sockaddr_in
addr_srv;
struct
hostentptrHost;
char
response[4096];
charpszHost;
charmsg
=
“HELLO
SERVER“;
if
(argc
==
3)
{
pszHost
=
argv[1];
iPort
=
atoi(argv[2]);
}
else
{
printf(“Usage:/t
client1
[hostname]
[portno]“);
return
1;
}
InitSockets();
sd_client
=
socket(PF_INET,SOCK_STREAM,0);
if
(sd_client
==
INVALID_SOCKET)
WSA_ERROR(“no
more
socket
resources“)
//輸入了數字格式的主機名,則直接轉換,否則通過gethostbyname獲取主機IP
if
(atoi(pszHost))
{
u_long
ip_addr
=
inet_addr(pszHost);
ptrHost
=
gethostbyaddr((char)
}
else
ptrHost
=
gethostbyname(pszHost);
if
(!ptrHost)
WSA_ERROR(“cannot
resolve
hostname“)
addr_srv.sin_family
=
PF_INET;
memcpy((char)
addr_srv.sin_port
=
htons(iPort);
//向服務器發出連接請求
err
=
connect(sd_client,(struct
sockaddr)
if
(err
==
INVALID_SOCKET)
WSA_ERROR(“cannot
connect
to
server“)
printf(“You
are
connected
to
the
server/n“);
//連接上后,向服務器發出服務請求
send
(sd_client,msg,strlen(msg)+1,0);
memset(response,0,sizeof(response));
//接收服務器返回的服務信息
recv(sd_client,response,sizeof(response),0);
printf(“server
says
%s/n“,response);
closesocket(sd_client);
WSACleanup();
return
0;
}
總結
以上是生活随笔為你收集整理的计算机课实验三,成都信息工程学院计算机网络课程实验三的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: etf就是股票吗?
- 下一篇: 建行日申月赎什么意思?