Linux網絡編程基礎試驗_第1頁
Linux網絡編程基礎試驗_第2頁
Linux網絡編程基礎試驗_第3頁
Linux網絡編程基礎試驗_第4頁
Linux網絡編程基礎試驗_第5頁
已閱讀5頁,還剩28頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

本文格式為Word版,下載可任意編輯——Linux網絡編程基礎試驗

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

試驗二Linux網絡編程基礎試驗(4學時)

一、試驗目的

了解TCP/IP協(xié)議通信的基本原理;

把握Socket網絡通信應用程序接口;

把握TCP、UDP簡單網絡程序(服務器端和客戶端)的編程方法;理解I/O復用模型。

二、試驗內容

UDP客戶端程序設計;

TCP客戶端程序設計;

簡易Web服務器程序設計。

三、預備知識

Linux操作系統(tǒng)應用、C語言程序設計

四、試驗設備及工具

硬件:PC機1臺。

軟件:虛擬機Linux,Gcc,VIM。

五、試驗原理

程序進行網絡通信時,是通過IP地址和套接字來訪問一個主機的。

1.IP地址

IP地址的作用是標識計算機的網卡地址,每一臺計算機都有一個IP地址。在程序中是通過IP地址來訪問一臺計算機的。IP地址是32位長度的二進制數(shù)值,存儲空間是4個字節(jié)。例如11000000

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

101010000000000100000110是一臺計算機的IP地址。IP地址可以使用點分十進制來表示,。

2.端口

所謂端口,是指計算機中為了標識在計算機中訪問網絡的不同程序而設的編號。端口號是一個16位的無符號整數(shù),對應的十進制取值范圍是0~65535。

3.TCP與UDP

TCP與UDP是兩種不同的網絡傳輸方式。兩個不同計算機中的程序,使用IP地址和端口,要使用一種約定的方法進行數(shù)據(jù)傳輸。TCP與UDP就是網絡中的兩種數(shù)據(jù)傳輸約定,主要的區(qū)別是進行數(shù)據(jù)傳輸時是否進行連接。

TCP:TCP是一種面向連接的網絡傳輸方式。這種方式是可靠的,缺點是傳輸過程繁雜,需要占用較多的網絡資源。

UDP:UDP是一種不面向連接的傳輸方式。對傳輸可靠性要求不高時,可以選擇使用這種傳輸方式。

4.套接字

區(qū)分不同應用程序進程間的網絡通信和連接,主要使用3個參數(shù)。通信的目的IP地址、使用的傳輸層協(xié)議(TCP或UDP)和使用的端口號。在編程時,就是使用這三個參數(shù)來構成一個套接字。這個套接字相當于一個接口,可以進行不同計算機程序的信息傳輸。

套接字相關的數(shù)據(jù)類型:

sockaddr用來保存一個套接字,定義方法如下所示。

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

structsockaddr{

//指定通信的地址類型。假使是TCP/IP通信,則該值為

AF_INET。

unsignedshortintsa_family;

//最多使用14個字符長度,用來保存IP地址和端口信息。charsa_data[14];

};

socketaddr_in為了便利初始化端口號、IP地址等信息。

structsocketaddr_in{

unsignedshortintsin_family;

uint16_tsin_port;//套接字使用的端口號

structin_addrsin_addr;//需要訪問的IP地址

unsignedcharsin_zero[8];//未使用的字段,填充為0

};

套接字類型指的是在網絡通信中不同的數(shù)據(jù)傳輸方式。例如UDP和TCP就是兩種不同的套接字類型。常用的套接字類型有面3種:流套接字(SOCK_STREAM)、數(shù)據(jù)報套接字(SOCK_DGRAM)、原始套接字(SOCK_RAW)。

5.重要的SocketAPI

(1)socket(建立一個socket通信)

相關函數(shù)accept,bind,connect,listen

表頭文件#includesys/types.h

#includesys/socket.h

定義函數(shù)intsocket(intdomain,inttype,intprotocol);

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

函數(shù)說明socket()用來建立一個新的socket,也就是向系統(tǒng)注冊,通知系

統(tǒng)建立一通信端口。參數(shù)domain指定使用何種的地址類型,

完整的定義在/usr/include/bits/socket.h內,底下是常見的協(xié)議:

PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCALUNIX進程通信

協(xié)議

PF_INET?AF_INETIpv4網絡協(xié)議

PF_INET6/AF_INET6Ipv6網絡協(xié)議

PF_IPX/AF_IPXIPX-Novell協(xié)議

PF_NETLINK/AF_NETLINK核心用戶接口裝置

PF_X25/AF_X25ITU-TX.25/ISO-8208協(xié)議

PF_AX25/AF_AX25業(yè)余無線AX.25協(xié)議

PF_ATMPVC/AF_ATMPVC存取原始ATMPVCs

PF_APPLETALK/AF_APPLETALKappletalk(DDP)協(xié)議

PF_PACKET/AF_PACKET初級封包接口

參數(shù)type有以下幾種數(shù)值:

SOCK_STREAM提供雙向連續(xù)且可信賴的數(shù)據(jù)流,即TCP。

支持

OOB機制,在所有數(shù)據(jù)傳送前必需使用connect()來建立連線

狀態(tài)。

SOCK_DGRAM使用不連續(xù)不可信賴的數(shù)據(jù)包連接

SOCK_SEQPACKET提供連續(xù)可信賴的數(shù)據(jù)包連接

SOCK_RAW提供原始網絡協(xié)議存取

SOCK_RDM提供可信賴的數(shù)據(jù)包連接

SOCK_PACKET提供和網絡驅動程序直接通信。

protocol用來指定socket所使用的傳輸協(xié)議編號,尋常此參考

不用管它,設為0即可。

返回值成功則返回socket處理代碼,失敗返回-1。

錯誤代碼EPROTONOSUPPORT參數(shù)domain指定的類型不支持參數(shù)

type或protocol指定的協(xié)議

ENFILE核心內存不足,無法建立新的socket結構

EMFILE進程文件表溢出,無法再建立新的socket

EACCESS權限不足,無法建立type或protocol指定的協(xié)議

ENOBUFS/ENOMEM內存不足

EINVAL參數(shù)domain/type/protocol不合法

(2)bind(綁定socket)

相關函數(shù)socket,accept,connect,listen

表頭文件#includesys/types.h

#includesys/socket.h

定義函數(shù)intbind(intsockfd,structsockaddr*my_addr,intaddrlen);

函數(shù)說明bind()用來設置給參數(shù)sockfd的socket一個名稱。此名稱由參數(shù)my_addr指向一

sockaddr結構,對于不同的socketdomain定義了一個通用的數(shù)據(jù)結構

structsockaddr

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

{

unsignedshortintsa_family;

charsa_data[14];

};

sa_family為調用socket()時的domain參數(shù),即AF_xxxx值。

sa_data最多使用14個字符長度。

此sockaddr結構會因使用不同的socketdomain而有不同結構定義,例如使用

AF_INETdomain,其socketaddr結構定義便為

structsocketaddr_in

{

unsignedshortintsin_family;

uint16_tsin_port;

structin_addrsin_addr;

unsignedcharsin_zero[8];

};

structin_addr

{

uint32_ts_addr;

};

sin_family即為sa_family

sin_port為使用的port編號

sin_addr.s_addr為IP地址

sin_zero未使用。

參數(shù)addrlen為sockaddr的結構長度。

返回值成功則返回0,失敗返回-1,錯誤原因存于errno中。

錯誤代碼EBADF參數(shù)sockfd非合法socket處理代碼。

EACCESS權限不足

ENOTSOCK參數(shù)sockfd為一文件描述詞,非socket。

(3)listen(等待連接)

相關函數(shù)socket,bind,accept,connect

表頭文件#includesys/socket.h

定義函數(shù)intlisten(ints,intbacklog);

函數(shù)說明listen()用來等待參數(shù)s的socket連線。參數(shù)backlog指定同時能處理的最大連接要

求,假使連接數(shù)目達此上限則client端將收到ECONNREFUSED的錯誤。Listen()

并未開始接收連線,只是設置socket為listen模式,真正接收client端連線的是

accept()。尋常listen()會在socket(),bind()之后調用,接著才調用accept()。

返回值成功則返回0,失敗返回-1,錯誤原因存于errno

附加說明listen()只適用SOCK_STREAM或SOCK_SEQPACKET的socket類型。假使socket

為AF_INET則參數(shù)backlog最大值可設至128。

錯誤代碼EBADF參數(shù)sockfd非合法socket處理代碼

EACCESS權限不足

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

EOPNOTSUPP指定的socket并未支援listen模式。

(4)connect(建立socket連接)

相關函數(shù)socket,bind,listen

表頭文件#includesys/types.h

#includesys/socket.h

定義函數(shù)intconnect(intsockfd,structsockaddr*serv_addr,intaddrlen);

函數(shù)說明connect()用來將參數(shù)sockfd的socket連至參數(shù)serv_addr指定的網絡地址。結構

sockaddr請參考bind()。參數(shù)addrlen為sockaddr的結構長度。

返回值成功則返回0,失敗返回-1,錯誤原因存于errno中。

錯誤代碼EBADF參數(shù)sockfd非合法socket處理代碼

EFAULT參數(shù)serv_addr指針指向無法存取的內存空間

ENOTSOCK參數(shù)sockfd為一文件描述詞,非socket。

EISCONN參數(shù)sockfd的socket已是連線狀態(tài)

ECONNREFUSED連線要求被server端拒絕。

ETIMEDOUT企圖連線的操作超過限定時間仍未有響應。

ENETUNREACH無法傳送數(shù)據(jù)包至指定的主機。

EAFNOSUPPORTsockaddr結構的sa_family不正確。

EALREADYsocket為不可阻斷且從前的連線操作還未完成。

(5)accept(接受socket連線)

相關函數(shù)socket,bind,listen,connect

表頭文件#includesys/types.h

#includesys/socket.h

定義函數(shù)intaccept(ints,structsockaddr*addr,int*addrlen);

函數(shù)說明accept()用來接受參數(shù)s的socket連線。參數(shù)s的socket必需先經bind()、listen()

函數(shù)處理過,當有連線進來時accept()會返回一個新的socket處理代碼,往后的數(shù)

據(jù)傳送與讀取就是經由新的socket處理,而原來參數(shù)s的socket能繼續(xù)使用accept()

來接受新的連線要求。連線成功時,參數(shù)addr所指的結構會被系統(tǒng)填入遠程主機

的地址數(shù)據(jù),參數(shù)addrlen為scokaddr的結構長度。關于結構sockaddr的定義請參

考bind()。

返回值成功則返回新的socket處理代碼,失敗返回-1,錯誤原因存于errno中。

錯誤代碼EBADF參數(shù)s非合法socket處理代碼。

EFAULT參數(shù)addr指針指向無法存取的內存空間。

ENOTSOCK參數(shù)s為一文件描述詞,非socket。

EOPNOTSUPP指定的socket并非SOCK_STREAM。

EPERM防火墻拒絕此連線。

ENOBUFS系統(tǒng)的緩沖內存不足。

ENOMEM核心內存不足。

(6)send(經socket傳送數(shù)據(jù))

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

相關函數(shù)sendto,sendmsg,recv,recvfrom,socket

表頭文件#includesys/types.h

#includesys/socket.h

定義函數(shù)intsend(ints,constvoid*msg,intlen,unsignedintfalgs);

函數(shù)說明send()用來將數(shù)據(jù)由指定的socket傳給對方主機。參數(shù)s為已建立好連接的socket。

參數(shù)msg指向欲連線的數(shù)據(jù)內容,參數(shù)len則為數(shù)據(jù)長度。參數(shù)flags一般設0,

其他數(shù)值定義如下

MSG_OOB傳送的數(shù)據(jù)以out-of-band送出。

MSG_DONTROUTE取消路由表查詢

MSG_DONTWAIT設置為不可阻斷運作

MSG_NOSIGNAL此動作不愿被SIGPIPE信號中斷。

返回值成功則返回實際傳送出去的字符數(shù),失敗返回-1。錯誤原因存于errno

錯誤代碼EBADF參數(shù)s非合法的socket處理代碼。

EFAULT參數(shù)中有一指針指向無法存取的內存空間

ENOTSOCK參數(shù)s為一文件描述詞,非socket。

EINTR被信號所中斷。

EAGAIN此操作會令進程阻斷,但參數(shù)s的socket為不可阻斷。

ENOBUFS系統(tǒng)的緩沖內存不足

ENOMEM核心內存不足

EINVAL傳給系統(tǒng)調用的參數(shù)不正確。

(7)sendto(經socket傳送數(shù)據(jù))

相關函數(shù)send,sendmsg,recv,recvfrom,socket

表頭文件#includesys/types.h

#includesys/socket.h

定義函數(shù)intsendto(ints,constvoid*msg,intlen,unsignedintflags,const

structsockaddr*to,inttolen);

函數(shù)說明sendto()用來將數(shù)據(jù)由指定的socket傳給對方主機。參數(shù)s為已建好連線的socket,

假使利用UDP協(xié)議則不需經過連線操作。參數(shù)msg指向欲連線的數(shù)據(jù)內容,參數(shù)

flags一般設0,詳細描述請參考send()。參數(shù)to用來指定欲傳送的網絡地址,結

構sockaddr請參考bind()。參數(shù)tolen為sockaddr的結果長度。

返回值成功則返回實際傳送出去的字符數(shù),失敗返回-1,錯誤原因存于errno中。

錯誤代碼同send。

(8)recv(經socket接收數(shù)據(jù))

相關函數(shù)recvfrom,recvmsg,send,sendto,socket

表頭文件#includesys/types.h

#includesys/socket.h

定義函數(shù)intrecv(ints,void*buf,intlen,unsignedintflags);

函數(shù)說明recv()用來接收遠端主機經指定的socket傳來的數(shù)據(jù),并把數(shù)據(jù)存到由參數(shù)buf指

向的內存空間,參數(shù)len為可接收數(shù)據(jù)的最大長度。

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

參數(shù)flags一般設0。其他數(shù)值定義如下:

MSG_OOB接收以out-of-band送出的數(shù)據(jù)。

MSG_PEEK返回來的數(shù)據(jù)并不會在系統(tǒng)內刪除,假使再調用recv()會返回一致的

數(shù)據(jù)內容。

MSG_WAITALL強迫接收到len大小的數(shù)據(jù)后才能返回,除非有錯誤或信號產生。

MSG_NOSIGNAL此操作不愿被SIGPIPE信號中斷返回值成功則返回接收到的字

符數(shù),失敗返回-1,錯誤原因存于errno中。

錯誤代碼同send

(9)recvfrom(經socket接收數(shù)據(jù))

相關函數(shù)recv,recvmsg,send,sendto,socket

表頭文件#includesys/types.h

#includesys/socket.h

定義函數(shù)intrecvfrom(ints,void*buf,intlen,unsignedintflags,structsockaddr*from,int

*fromlen);

并把數(shù)據(jù)存到由參數(shù)buf指函數(shù)說明recv()用來接收遠程主機經指定的socket傳來的數(shù)據(jù),

向的內存空間,參數(shù)len為可接收數(shù)據(jù)的最大長度。參數(shù)flags一般設0,其他數(shù)

值定義請參考recv()。參數(shù)from用來指定欲傳送的網絡地址,結構sockaddr請參

考bind()。參數(shù)fromlen為sockaddr的結構長度。

返回值成功則返回接收到的字符數(shù),失敗則返回-1,錯誤原因存于errno中。

錯誤代碼同send。

(10)select(I/O復用機制)

表頭文件#includesys/time.h

#includesys/types.h

#includeunistd.h

定義函數(shù)intselect(intn,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,structtimeval*

timeout);

函數(shù)說明select()用來等待文件描述詞狀態(tài)的改變。參數(shù)n代表最大的文件描述詞加1,參數(shù)

readfds、writefds和exceptfds稱為描述詞組,是用來回傳該描述詞的讀,寫或例

外的狀況。底下的宏提供了處理這三種描述詞組的方式:

FD_CLR(inrfd,fd_set*set);用來清除描述詞組set中相關fd的位

FD_ISSET(intfd,fd_set*set);用來測試描述詞組set中相關fd的位是否為真

FD_SET(intfd,fd_set*set);用來設置描述詞組set中相關fd的位

FD_ZERO(fd_set*set);用來清除描述詞組set的全部位

參數(shù)timeout為結構timeval,用來設置select()的等待時間,其結構定義如下

structtimeval

{

time_ttv_sec;

time_ttv_usec;

};

返回值假使參數(shù)timeout設為NULL則表示select()沒有timeout。

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

錯誤代碼執(zhí)行成功則返回文件描述詞狀態(tài)已改變的個數(shù),假使返回0代表在描述詞狀態(tài)改

變前已超過timeout時間,當有錯誤發(fā)生時則返回-1,錯誤原因存于errno,此時參

數(shù)readfds,writefds,exceptfds和timeout的值變成不可預計。

EBADF文件描述詞為無效的或該文件已關閉

EINTR此調用被信號所中斷

EINVAL參數(shù)n為負值。

ENOMEM核心內存不足

范例常見的程序片段:fs_setreadset;

FD_ZERO(readset);

FD_SET(fd,readset);

select(fd+1,readset,NULL,NULL,NULL);

if(FD_ISSET(fd,readset){……}

6.其他函數(shù)

(1)inet_ntoa函數(shù)說明:

函數(shù)將網絡字節(jié)排序的地址轉換為標準的ASCII以點分開的地址(格式如:ddd.ddd.ddd.ddd)。

1)函數(shù)原型:

char*inet_ntoa(structin_addrin);

2)函數(shù)相關頭文件:

#includesys/socket.h

#includenetinet/in.h

#includearpa/inet.h

3)函數(shù)的參數(shù)說明:

in:待轉換的IP地址結構。

4)函數(shù)返回值:

該函數(shù)返回指向點分開的字符串地址的指針,該字符串的空間為靜態(tài)分派的,這意味著在其次次調用該函數(shù)時,上一次調用將會被重寫(復蓋),所以適當?shù)臅r候需要保存該串。

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

(2)inet_addr函數(shù)說明:

函數(shù)轉換網絡主機地址(如0)為網絡字節(jié)序二進制值。

1)函數(shù)原型:

in_addr_tinet_addr(constchar*cp);

2)函數(shù)相關頭文件:

同(1)。

3)函數(shù)的參數(shù)說明:

cp為待轉換的IP地址字符串指針。

4)函數(shù)返回值:

假使參數(shù)char*cp無效,函數(shù)返回-1(INADDR_NONE),這個函數(shù)在處理地址為55時也返回-1。

inet_aton和inet_ntoa只能用來來處理IPv4版本的網絡字節(jié)和主機字節(jié)之間的轉換。函數(shù)inet_pton和inet_ntop能夠兼容地處理IPv4和IPv6。

(3)inet_pton函數(shù)說明

1)函數(shù)原型:

intinet_pton(intaf,constchar*src,void*dst);

2)函數(shù)相關頭文件:

#includesys/types.h

#includesys/socket.h

#includearpa/inet.h

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

3)函數(shù)的參數(shù)說明:

函數(shù)轉換ASCII類型的地址到網絡字節(jié)序二進制結構。

af:協(xié)議族;

src:待轉換IP地址指針,指向字符型的地址;

dst:轉換結果,網絡順序格式的地址。

4)函數(shù)返回值:

執(zhí)行成功返回1;假使函數(shù)出錯將返回-1,并將errno設置為

EAFNOSUPPORT;假使參數(shù)af指定的地址族和src格式不對,函數(shù)將返回0。

(4)inet_ntop函數(shù)說明:

函數(shù)轉換網絡字節(jié)序二進制結構到ASCII類型的地址。

1)函數(shù)原型:

constchar*inet_ntop(intaf,constvoid*src,char*dst,socklen_tcnt);

2)函數(shù)相關頭文件:

同inet_pton。

3)函數(shù)的參數(shù)說明:

cnt為緩沖區(qū)dst的大??;其它同inet_pton。

4)函數(shù)返回值:

成功時返回字符地址的指針;出錯時則返回一個空指針,并將errno置為ENOSPC。

(5).存儲順序轉換

由于每一個機器內部對變量的字節(jié)存儲順序不同(分為大端和小

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

端存儲),而網絡傳輸?shù)臄?shù)據(jù)一定是統(tǒng)一的順序,即網絡字節(jié)順序。所以要調用轉換函數(shù),將網絡中傳輸?shù)淖止?jié)順序進行統(tǒng)一。

頭文件netinet/in.h中定義了一組轉換函數(shù),原型如下:uint16_thtons(uint16_thost16bitvalue);

“HosttoNetworkShort〞主機字節(jié)順序轉換為網絡字節(jié)順序(對無符號短型進行操作4bytes)。

uint32_thtonl(uint32_thost32bitvalue);

“HosttoNetworkLong〞主機字節(jié)順序轉換為網絡字節(jié)順序(對無符號長型進行操作8bytes)。

以上兩個函數(shù)均返回網絡字節(jié)序。

uint16_tntohs(uint16_tnet16bitvalue);

“NetworktoHostShort〞網絡字節(jié)順序轉換為主機字節(jié)順序(對無符號短型進行操作4bytes)。

uint32_tntohl(uint32_tnet32bitvalue);

“NetworktoHostLong〞網絡字節(jié)順序轉換為主機字節(jié)順序(對無符號長型進行操作8bytes)。

以上兩個函數(shù)均返回主機字節(jié)序。

五、試驗步驟

0、準備工作

將虛擬機網絡連接設置為橋接方式(自定義-VMnet0);在虛擬機Linux系統(tǒng)中設置網絡設備設置為自動獲取IP地址方式(DHCP),讓后通過ipconfig命令查看eth0的IP地址,并記錄。步驟

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

為:RedHat主菜單-系統(tǒng)設置-網絡,編輯按鈕,選擇單項選擇按鈕“自動獲取IP地址設置使用〞。

設置完畢的檢測方法:可以兩個同學之間使用ping命令相互測試。

1、UDP客戶端程序設計

設計一個基于UDP協(xié)議(SOCK_DGRAM類型套接字)的客戶端程序。程序的功能為,向教師機服務器端程序發(fā)送字符串(內容:學號+姓名)。服務器端的IP地址默認為17(或臨時通知),端口號為5555。

(1)使用Linux下的VIM編寫代碼。參考程序udpclient.c://*****UDPClient.c#includesys/types.h#includesys/socket.h#includenetinet/in.h#includeerrno.h#includetime.h#includestring.h#includestdio.h#defineBUFFLEN1024#defineSERVER_PORT5555intmain(intargc,char*argv[]){

ints;

structsockaddr_inserver;

time_tnow;

charbuff[BUFFLEN];

intn=0;

intlen=0;

s=socket(AF_INET,SOCK_DGRAM,0);

if(s0){

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

fprintf(stderr,SocketError:%s\n,strerror(errno));

exit(1);

}

memset(server,0,sizeof(server));server.sin_family=AF_INET;

//服務器端IP地址,請根據(jù)需要進行設定

if(argv[1]){

server.sin_addr.s_addr=inet_addr(argv[1]);

}else{

server.sin_addr.s_addr=inet_addr(17);

}

server.sin_port=htons(SERVER_PORT);memset(buff,0,BUFFLEN);

strcpy(buff,1089114100學生姓名全拼);

sendto(s,buff,strlen(buff),0,(structsockaddr*)server,

sizeof(server));memset(buff,0,BUFFLEN);

len=sizeof(server);

n=recvfrom(s,buff,BUFFLEN,0,(structsockaddr*)server,len);if(n0){

printf(Received:%s\n,buff);

}

close(s);

return0;

}

(2)在終端窗口中對程序進行編譯。命令如下:

makeudpclient

如無錯誤,將會產生test2udpclient可執(zhí)行文件,運行./udpclient,觀測教師機服務端。

2、TCP客戶端程序設計

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

本頁已使用福昕閱讀器進行編輯。

福昕軟件(C)2005-2009,版權所有,

僅供試用。

在上述試驗中,假使服務器端故障或網絡線路故障,將導致的數(shù)據(jù)發(fā)送不成功稱為丟包,但這樣的錯誤,UDP客戶端程序卻無從覺察,同時客戶端也無法獲知服務器端是否準備就緒。設計一個基于TCP協(xié)議(SOCK_STREAM類型套接字)的客戶端程序。程序的功能為,向教師機服務器端程序發(fā)送字符串(內容:學號+姓名)。服務器端的IP地址默認為17(或臨時通知),端口號為6666。程序中增加對connect函數(shù)連接成功與否的判斷,連接成功后發(fā)送上述字符串,反之提醒連接錯誤信息。

(1)使用Linux下的VIM編寫代碼。參考程序tcpclient.c:/*******客戶端程序TCPClient.c************/#includestdlib.h#includestdio.h#includeerrno.h#includestring.h#includenetdb.h#includesys/types.h#includenetinet/in.h#includesys/socket.h#defineBUFFLEN1024

#defineSERVER_PORT6666intmain(intargc,char*argv[]){

intsockfd;

charbuffer[BUFFLEN];

structsockaddr_inserver_addr;intn;

/*客戶程序開始建立sockfd描述符*/

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){

fprintf(stderr,SocketError:%s\a\n,strerror(errno));

exit(1);

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

}/*客戶程序填充服務端的資料*/

bzero(server_addr,sizeof(server_addr));

server_addr.sin_family=AF_INET;

server_addr.sin_port=htons(SERVER_PORT);

if(argv[1]){

server_addr.sin_addr.s_addr=inet_addr(argv[1]);

}else{

server_addr.sin_addr.s_addr=inet_addr(17);}/*客戶程序發(fā)起連接請求*/

if(connect(sockfd,(structsockaddr*)(server_addr),sizeof(structsockaddr))==-1){fprintf(stderr,ConnectError:%s\a\n,strerror(errno));

exit(1);

}else{

printf(OK:connectsuccess!\n);}/*連接成功*/

memset(buffer,0,BUFFLEN);

strcpy(buffer,1089114100學生姓名的全拼);

send(sockfd,buffer,strlen(buffer),0);

memset(buffer,0,BUFFLEN);n=recv(sockfd,buffer,BUFFLEN,0);if(n0){printf(Received:%s\n,buffer);

}

/*終止通訊*/

close(sockfd);

exit(0);

}

(2)在終端窗口中對程序進行編譯。命令如下:

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

maketcpclient

如無錯誤,將會產生tcpclient可執(zhí)行文件,兩次運行./tcpclient,第一次給出一個錯誤的服務器端IP地址或端口號,觀測本機錯誤提醒信息,驗證TCP為可靠連接方式;其次次給出正確的服務器IP地址和端口號,觀測教師機服務端。

3、簡易Web服務器

設計一個簡易Web服務器程序,端口為80,該服務器程序運行后可通過瀏覽器訪問到一個簡易Web頁面,頁面主要信息為本人“學號+姓名〞??赏瑢W之間相互訪問驗證。

(1)編寫代碼。簡易Web服務器參考程序websvr.c:/*簡易Web服務器程序*/#includestdlib.h#includestdio.h#includeerrno.h#includestring.h#includesys/types.h

#includenetinet/in.h

#includesys/wait.h

#includesys/socket.h#definePORT80

#defineBACKLOG10#defineLENGTH1024

charhttpweb[]={HTTP/1.0200OK\r\nDate:Sun,17Apr20232023:10:00GMT\r\nServer:tinyHttp/1.00891141Corporation\r\nAccept-Ranges:bytes\r\nConnection:Keep-Close\r\n

Content-Type:text/html\r\n

了解SOCKET編程,熟悉C/S模式服務器和客戶端。

charweb[]={

HTML\r\nHEAD\r\n

TITLE演示網頁/TITLE\r\n

BODYaLink=greenbgColor=#f1f1ddlink=red\r\nvLink=#321afd\r\n

H1HELLOWELCOMETOEMBEDDED

WEBSERVER/H1\r\n

/HTML\r\n

};intmain(){

intsockfd;

//Socketfiledescriptor

intnsockfd;

//NewSocketfiledescriptor

inti,num;

intflag=1;

intsin_size;

//tostorestructsize

charrevbuf[LENGTH];

structsockaddr_inaddr_local;

structsockaddr_inaddr_remote;/*GettheSocketfiledescriptor*/

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){printf(ERROR:CannotobtainSocketDespcritor\n);return(0);

了解SOCKET編程,熟悉C/S模式服務器和客戶端

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論