中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

現(xiàn)在哪些網(wǎng)站做外貿(mào)的好做拉新人拿獎(jiǎng)勵(lì)的app

現(xiàn)在哪些網(wǎng)站做外貿(mào)的好做,拉新人拿獎(jiǎng)勵(lì)的app,國人在線做網(wǎng)站,淘寶客購物網(wǎng)站的怎么做1.TCP/IP編程 1.1 概念 IP 是英文 Internet Protocol (網(wǎng)絡(luò)之間互連的協(xié)議)的縮寫,也就是為計(jì)算機(jī)網(wǎng)絡(luò)相互連接進(jìn)行通信而設(shè)計(jì)的協(xié)議。任一系統(tǒng),只要遵守 IP協(xié)議就可以與因特網(wǎng)互連互通。 所謂IP地址就是給每個(gè)遵循tcp/ip協(xié)議連…

1.TCP/IP編程

1.1 概念

IP 是英文 Internet Protocol (網(wǎng)絡(luò)之間互連的協(xié)議)的縮寫,也就是為計(jì)算機(jī)網(wǎng)絡(luò)相互連接進(jìn)行通信而設(shè)計(jì)的協(xié)議。任一系統(tǒng),只要遵守 IP協(xié)議就可以與因特網(wǎng)互連互通。

所謂IP地址就是給每個(gè)遵循tcp/ip協(xié)議連接在Internet上的主機(jī)分配的一個(gè)32bit地址。按照TCP/IP協(xié)議規(guī)定,IP地址用二進(jìn)制來表示,每個(gè)IP地址長32bit,比特?fù)Q算成字節(jié),就是4個(gè)字節(jié)。為了方便人們的使用,IP地址經(jīng)常被寫成十進(jìn)制的形式,中間使用符號(hào) “.” 分開不同的字節(jié),如:192.168.1.1。在因特網(wǎng)中,主機(jī)的標(biāo)識(shí)便是它ip地址。

常見的獲取服務(wù)器ip的方法是使用系統(tǒng)自帶的ping命令。例,打開cmd輸入:ping http://www.xxxx.com

1.2 Socket

socket的英文原義是“孔”或“插座”。作為4BDS UNIX的進(jìn)程通信機(jī)制,取后一種意思。通常也稱作”套接字”,用于描述IP地址和端口,是一個(gè)通信鏈的句柄。Scoket程勛分為服務(wù)端與客戶端,服務(wù)端程序監(jiān)聽端口,等待客戶端程序的連接??蛻舳顺绦虬l(fā)起連接,等待服務(wù)端的相應(yīng)??蛻舳讼胍B接上服務(wù)端的話,需要 知道服務(wù)端的ip地址。

例如,客戶想要訪問百度網(wǎng)站的首頁,通過瀏覽器訪問http://www.baidu.com。瀏覽器發(fā)出請(qǐng)求之后,先是DNS服務(wù)器將百度的域名解析成ip地址之后,訪問到ip地址為115.239.210.27服務(wù)器的80端口(http協(xié)議默認(rèn)在80端口),請(qǐng)求發(fā)送后,百度的服務(wù)器作為響應(yīng)將頁面的源代碼發(fā)送至客戶端(通過瀏覽器右鍵->源代碼,或者ctrl+u到服務(wù)器返回的頁面源代碼),隨后瀏覽器將源代碼渲染成頁面。這樣用戶就看到了百度網(wǎng)站的

1.3 服務(wù)端與客戶端

服務(wù)端與客戶端在計(jì)算機(jī)的世界里,凡是提供服務(wù)的一方我們稱為服務(wù)端(Server),而接受服務(wù)的另一方我們稱作客戶端(Client)。網(wǎng)站提供網(wǎng)頁數(shù)據(jù)的服務(wù),使用者接受網(wǎng)站所提供的數(shù)據(jù)服務(wù),所以使用者在這里就是客戶端,響應(yīng)使用者要求的網(wǎng)站即稱為服務(wù)端。不過客戶端及服務(wù)端的關(guān)系不見得一定建立在兩臺(tái)分開的機(jī)器上,同一臺(tái)機(jī)器中也有這種主從關(guān)系的存在,提供服務(wù)的服務(wù)端及接受服務(wù)的客戶端也有可能都在同一臺(tái)機(jī)器上。例如我們?cè)谔峁┚W(wǎng)頁的服務(wù)器上執(zhí)行瀏覽器瀏覽本機(jī)所提供的網(wǎng)頁,這樣在同一臺(tái)機(jī)器上就同時(shí)扮演服務(wù)端及客戶端。

實(shí)現(xiàn)流程:

服務(wù)器端創(chuàng)建套接字后連續(xù)調(diào)用bind、listen函數(shù)進(jìn)入等待狀態(tài),客戶端通過調(diào)用connect函數(shù)發(fā)起連接請(qǐng)求。需要注意的是,客戶端只能等到服務(wù)器調(diào)用listen函數(shù)后才能調(diào)用connect()函數(shù)。同時(shí)要清楚,客戶端調(diào)用connect()函數(shù)前,服務(wù)器端有可能率先調(diào)用accept()函數(shù)。當(dāng)然,此時(shí)服務(wù)器在調(diào)用accept()函數(shù)是進(jìn)入阻塞狀態(tài),直到客戶端調(diào)用connect()函數(shù)為止。

2、Windows與Linux下TCP/IP編程

2.1 函數(shù)說明

Windows套接字大部分是參考BSD系列UNIX套接字設(shè)計(jì)的,所以很多地方都跟Linux套接字類似。大多數(shù)項(xiàng)目都在Linux系列的操作系統(tǒng)下開發(fā)服務(wù)器端,而多數(shù)客戶端是在windows平臺(tái)下開發(fā)的。

在windows下做網(wǎng)絡(luò)編程,需要做如下準(zhǔn)備:導(dǎo)入頭文件winsock2.h、鏈接ws2_32.lib。

Windows 下的 socket 程序和 Linux 思路相同,但細(xì)節(jié)有所差別:

Windows 下的 socket 程序依賴Winsock.dll 或 ws2_32.dll,必須提前加載。Windows Socket編程依賴于系統(tǒng)提供的動(dòng)態(tài)鏈接庫(DLL),有兩個(gè)版本:較早的DLL是 wsock32.dll,大小為 28KB,對(duì)應(yīng)的頭文件為 winsock1.h;最新的DLL是 ws2_32.dll,大小為 69KB,對(duì)應(yīng)的頭文件為 winsock2.h。幾乎所有的 Windows 操作系統(tǒng)都已經(jīng)支持 ws2_32.dll,包括個(gè)人操作系統(tǒng) Windows 95 OSR2、Windows 98、Windows Me、Windows 2000、XP、Vista、Win7、Win8、Win10 以及服務(wù)器操作系統(tǒng) Windows NT 4.0 SP4、Windows Server 2003、Windows Server 2008 等,所以你可以毫不猶豫地使用最新的 ws2_32.dll。

使用 DLL 之前必須把 DLL 加載到當(dāng)前程序,你可以在編譯時(shí)加載,也可以在程序運(yùn)行時(shí)加載。這里使用#pragma命令,在編譯時(shí)加載:#pragma comment (lib, “ws2_32.lib”)

使用 DLL 之前,還需要調(diào)用 WSAStartup() 函數(shù)進(jìn)行初始化,以指明 WinSock 規(guī)范的版本,并初始化相應(yīng)版本的庫。它的原型為:int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);

int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);wVersionRequested:該參數(shù)為WinSock 規(guī)范的版本號(hào),低字節(jié)為主版本號(hào),高字節(jié)為副版本號(hào)(修正版本號(hào));
lpWSAData:該參數(shù)為指向 WSAData 結(jié)構(gòu)體的指針;WinSock 規(guī)范的最新版本號(hào)為 2.2,較早的有 2.12.0、1.1、1.0,ws2_32.dll 支持所有的規(guī)范,而 wsock32.dll 僅支持 1.01.1。若版本為1.2,則其中1是主版本號(hào),2是副版本號(hào),應(yīng)傳遞0x0201。
wsock32.dll 已經(jīng)能夠很好的支持 TCP/IP 通信程序的開發(fā),ws2_32.dll 主要增加了對(duì)其他協(xié)議的支持,不過建議使用最新的 2.2 版本。wVersionRequested 參數(shù)用來指明我們希望使用的版本號(hào),它的類型為 WORD,等價(jià)于 unsigned short,是一個(gè)整數(shù),所以需要用 MAKEWORD() 宏函數(shù)對(duì)版本號(hào)進(jìn)行轉(zhuǎn)換。例如:
MAKEWORD(1, 2); //主版本號(hào)為1,副版本號(hào)為2,返回 0x0201
MAKEWORD(2, 2); //主版本號(hào)為2,副版本號(hào)為2,返回 0x0202

Linux 使用“文件描述符”的概念,而 Windows 使用“文件句柄”的概念;

Linux 中的一切都是文件,每個(gè)文件都有一個(gè)整數(shù)類型的文件描述符,socket 也是一個(gè)文件,也有文件描述符,所以Linux 不區(qū)分 socket 文件和普通文件,而 Windows 區(qū)分;

Linux 下 socket() 函數(shù)的返回值為 int 類型,而 Windows 下為 SOCKET 類型,也就是句柄。

Linux 下使用 read() / write() 函數(shù)讀寫,而 Windows 下使用 recv() / send() 函數(shù)發(fā)送和接收。

關(guān)閉 socket 時(shí),Linux 使用 close() 函數(shù),而 Windows 使用 closesocket() 函數(shù)。

socket編程的基本函數(shù)有socket()、bind()、listen()、accept()、send()、sendto()、recv()以及recvfrom()等。

2.2 socket()

Linux 中的一切都是文件,每個(gè)文件都有一個(gè)整數(shù)類型的文件描述符;socket 也是一個(gè)文件,也有文件描述符。使用 socket() 函數(shù)創(chuàng)建套接字以后,返回值就是一個(gè) int 類型的文件描述符。

Windows 會(huì)區(qū)分 socket 和普通文件,它把 socket 當(dāng)做一個(gè)網(wǎng)絡(luò)連接來對(duì)待,調(diào)用 socket() 以后,返回值是 SOCKET 類型,用來表示一個(gè)套接字。

不管是 Windows 還是 Linux,都使用 socket() 函數(shù)來創(chuàng)建套接字。socket() 在兩個(gè)平臺(tái)下的參數(shù)是相同的,不同的是返回值。

頭文件

Linux

#include <sys/socket.h>

Windows

#include <winsock2.h>

函數(shù)原型

Linux

int socket(int family,int type,int protocol);

Windows

SOCKET socket(int ?family, int type, int protocol);

作用

該函數(shù)用于創(chuàng)建一個(gè)套接字,同時(shí)指定協(xié)議和類型

參數(shù)

family:協(xié)議族(AF前綴和PF前綴是等價(jià)的)

AF_INET(PF_INET):IPv4協(xié)議族

AF_INET6(PF_INET6):IPv6協(xié)議族

AF_LOCAL:UNIX域協(xié)議族

AF_ROUTE:路由套接字協(xié)議族

AF_KEY:密鑰套接字協(xié)議族

type:套接字類型,即套接字的數(shù)據(jù)傳輸方式(有的協(xié)議族中存在多種數(shù)據(jù)傳輸方式,所以協(xié)議族和數(shù)據(jù)傳輸方式分開)

SOCK_STREAM:流式套接字

SOCK_DGRAM:數(shù)據(jù)報(bào)套接字

SOCK_RAM:原始套接字

Protocol:傳輸協(xié)議(該參數(shù)一般置0,原始套接字除外),比如滿足AF_INET和SOCK_STREAM這兩個(gè)條件的只有IPPROTO_TCP,滿足AF_INET和SOCK_DGRAM這兩個(gè)條件的只有IPPTOTO_UDP

IPPROTO_TCP:TCP協(xié)議

IPPTOTO_UDP:UDP協(xié)議

返回值

成功

Linux

非負(fù)套接字文件描述符

Windows

套接字句柄

失敗

Linux

-1

Windows

INVALID_SOCKET

注意:
protocol 表示傳輸協(xié)議,常用的有 IPPROTO_TCP 和 IPPTOTO_UDP,分別表示 TCP 傳輸協(xié)議和 UDP 傳輸協(xié)議。有了地址類型和數(shù)據(jù)傳輸方式,還不足以決定采用哪種協(xié)議嗎?為什么還需要第三個(gè)參數(shù)呢?

正如大家所想,一般情況下有了 af 和 type 兩個(gè)參數(shù)就可以創(chuàng)建套接字了,操作系統(tǒng)會(huì)自動(dòng)推演出協(xié)議類型,除非遇到這樣的情況:有兩種不同的協(xié)議支持同一種地址類型和數(shù)據(jù)傳輸類型。如果我們不指明使用哪種協(xié)議,操作系統(tǒng)是沒辦法自動(dòng)推演的。

當(dāng)參數(shù) family 的值為 PF_INET時(shí):

如果使用 SOCK_STREAM 傳輸數(shù)據(jù),那么滿足這兩個(gè)條件的協(xié)議只有 TCP,因此可以這樣來調(diào)用 socket() 函數(shù):

int tcp_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //IPPROTO_TCP表示TCP協(xié)議 這種套接字稱為 TCP 套接字

如果使用 SOCK_DGRAM 傳輸方式,那么滿足這兩個(gè)條件的協(xié)議只有 UDP,因此可以這樣來調(diào)用 socket() 函數(shù):

int udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); //IPPROTO_UDP表示UDP協(xié)議 這種套接字稱為 UDP 套接字

上面兩種情況都只有一種協(xié)議滿足條件,可以將 protocol 的值設(shè)為 0,系統(tǒng)會(huì)自動(dòng)推演出應(yīng)該使用什么協(xié)議,如下所示:

int tcp_socket = socket(AF_INET, SOCK_STREAM, 0); //創(chuàng)建TCP套接字

int udp_socket = socket(AF_INET, SOCK_DGRAM, 0); //創(chuàng)建UDP套接字

2.3 bind()

它主要用于服務(wù)器,客戶端創(chuàng)建的套接字可以不綁定地址。綁定時(shí)一般要指定IP地址和端口號(hào),否則內(nèi)核會(huì)隨意分配一個(gè)臨時(shí)端口給該套接字,IP地址可以是本機(jī)的IP地址,或者使用宏INADDR_ANY,允許將套接字與服務(wù)器的任意網(wǎng)絡(luò)接口(如eth0、eth0:1、eth1等)進(jìn)行綁定。

頭文件

Linux

#include <sys/socket.h>

Windows

#include <winsock2.h>

函數(shù)原型

Linux

int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen);

Windows

int bind(SOCKET sockfd, const struct sockaddr *addr, int addrlen);

作用

給服務(wù)器套接字分配IP地址和端口號(hào)

參數(shù)

sockfd

套接字描述符(服務(wù)器端socket函數(shù)的的返回值)

addr

綁定的地址(struct sockaddr_in強(qiáng)轉(zhuǎn))

addrlen

地址長度(sizeof(server_addr))

返回值

成功

Linux

0

Windows

0

失敗

Linux

-1

Windows

SOCKET_ERROR

2.4 listen()

在服務(wù)器端程序成功建立套接字并與地址進(jìn)行綁定之后,通過調(diào)用listen()函數(shù)將服務(wù)器套接字設(shè)置成被動(dòng)監(jiān)聽模式(被動(dòng)模式),并且設(shè)置客戶端請(qǐng)求連接的隊(duì)列長度。所謂被動(dòng)監(jiān)聽,是指套接字一直處于“睡眠”中,直到客戶端發(fā)起請(qǐng)求才會(huì)被“喚醒”。

頭文件

Linux

#include <sys/socket.h>

Windows

#include <winsock2.h>

函數(shù)原型

Linux

int listen(int sockfd, int backlog);

Windows

int listen(SOCKET sockfd, int backlog);

作用

該函數(shù)將服務(wù)器套接字轉(zhuǎn)為可接收連接狀態(tài)

參數(shù)

sockfd

套接字描述符(服務(wù)器端的套接字)

backlog

請(qǐng)求隊(duì)列中允許的最大請(qǐng)求數(shù),大多數(shù)系統(tǒng)默認(rèn)值為5,最大為1024

返回值

成功

Linux

0

Windows

0

失敗

Linux

-1

Windows

SOCKET_ERROR

sock 為需要進(jìn)入監(jiān)聽狀態(tài)的套接字,backlog 為請(qǐng)求隊(duì)列的最大長度。

所謂被動(dòng)監(jiān)聽,是指當(dāng)沒有客戶端請(qǐng)求時(shí),套接字處于“睡眠”狀態(tài),只有當(dāng)接收到客戶端請(qǐng)求時(shí),套接字才會(huì)被“喚醒”來響應(yīng)請(qǐng)求。

當(dāng)套接字正在處理客戶端時(shí),如果有新的客戶端請(qǐng)求進(jìn)來,套接字是沒法處理的,只能把它放進(jìn)緩沖區(qū)進(jìn)行排隊(duì),待當(dāng)前客戶端處理完畢后,再從緩沖區(qū)中讀取出來處理。如果不斷有新的請(qǐng)求進(jìn)來,它們就按照先后順序在緩沖區(qū)中排隊(duì),直到緩沖區(qū)滿。這個(gè)緩沖區(qū),就稱為請(qǐng)求隊(duì)列(Request Queue)。

緩沖區(qū)的長度(能存放多少個(gè)客戶端請(qǐng)求)可以通過 listen() 函數(shù)的 backlog 參數(shù)指定,但究竟為多少并沒有什么標(biāo)準(zhǔn),可以根據(jù)你的需求來定,并發(fā)量小的話可以是10或者20。

如果將 backlog 的值設(shè)置為 SOMAXCONN,就由系統(tǒng)來決定請(qǐng)求隊(duì)列長度,這個(gè)值一般比較大,可能是幾百,或者更多。

當(dāng)請(qǐng)求隊(duì)列滿時(shí),就不再接收新的請(qǐng)求,對(duì)于 Linux,客戶端會(huì)收到 ECONNREFUSED 錯(cuò)誤,對(duì)于 Windows,客戶端會(huì)收到 WSAECONNREFUSED 錯(cuò)誤。

注意:listen() 只是讓套接字處于監(jiān)聽狀態(tài),將各個(gè)客戶端的請(qǐng)求放入緩沖區(qū)進(jìn)行排隊(duì),并沒有處理客戶端的請(qǐng)求。接受請(qǐng)求需要使用 accept() 函數(shù)。

2.5 accept()

服務(wù)器端通過調(diào)用accept()函數(shù)等待并處理客戶端的連接請(qǐng)求,程序一旦執(zhí)行到 accept() 就會(huì)被阻塞(暫停運(yùn)行),直到客戶端發(fā)起請(qǐng)求。建立好TCP連接后,該函數(shù)會(huì)返回一個(gè)新的已連接的套接字。

頭文件

Linux

#include <sys/socket.h>

Windows

#include <winsock2.h>

函數(shù)原型

Linux

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

Windows

SOCKET accept(SOCKET sockfd, struct sockaddr *addr, int *addrlen);

作用

該函數(shù)用來處理連接請(qǐng)求,如果在沒有連接請(qǐng)求,該函數(shù)不會(huì)返回。一直到有連接請(qǐng)求為止

參數(shù)

sockfd

套接字描述符(服務(wù)器的套接字)

addr

用于保存連接的客戶端的地址

addrlen

地址長度

返回值

成功

Linux

建立好連接的套接字描述符

Windows

建立好連接的套接字句柄

失敗

Linux

-1

Windows

INVALID_SOCKET

accept()函數(shù)受理連接請(qǐng)求等待隊(duì)列呆處理的客戶端連接請(qǐng)求。函數(shù)調(diào)用成功時(shí),accept()函數(shù)內(nèi)部將產(chǎn)生用于數(shù)據(jù)I/O的套接字,并返回其文件描述符。需要強(qiáng)調(diào)的是,套接字是自動(dòng)創(chuàng)建的,并自動(dòng)與發(fā)起連接請(qǐng)求的客戶端建立連接

它的參數(shù)與 listen() 和 connect() 是相同的:sock 為服務(wù)器端套接字,addr 為 sockaddr_in 結(jié)構(gòu)體變量,addrlen 為參數(shù) addr 的長度,可由 sizeof() 求得。

accept() 返回一個(gè)新的套接字來和客戶端通信,addr 保存了客戶端的IP地址和端口號(hào),而 sock 是服務(wù)器端的套接字,大家注意區(qū)分。后面和客戶端通信時(shí),要使用這個(gè)新生成的套接字,而不是原來服務(wù)器端的套接字。

最后需要說明的是:listen() 只是讓套接字進(jìn)入監(jiān)聽狀態(tài),并沒有真正接收客戶端請(qǐng)求,listen() 后面的代碼會(huì)繼續(xù)執(zhí)行,直到遇到 accept()。accept() 會(huì)阻塞程序執(zhí)行(后面代碼不能被執(zhí)行),直到有新的請(qǐng)求到來。

2.6 connect()

客戶端通過該函數(shù)向服務(wù)器端的監(jiān)聽套接字發(fā)送連接請(qǐng)求,直到服務(wù)器傳回?cái)?shù)據(jù)后,connect() 才運(yùn)行結(jié)束。

客戶端調(diào)用connect()函數(shù)后,發(fā)生以下情況之一才會(huì)返回:服務(wù)器端接受連接請(qǐng)求、發(fā)生斷網(wǎng)等異常情況而中斷連接請(qǐng)求。

需要注意,所謂的“接受連接請(qǐng)求”并不意味著服務(wù)器端調(diào)用accept()函數(shù),其實(shí)是服務(wù)器端用listen()把客戶端連接請(qǐng)求信息記錄到等待隊(duì)列。因此connect()函數(shù)返回后并不立即進(jìn)行數(shù)據(jù)交換。

客戶端在調(diào)用connect()函數(shù)時(shí)會(huì)自動(dòng)給套接字分配IP地址和端口號(hào),不需要調(diào)用bind()函數(shù)進(jìn)行分配。

頭文件

Linux

#include <sys/socket.h>

Windows

#include <winsock2.h>

Linux

int connect(int sockfd, struct sockaddr *serv_addr, socklen_t addrlen);?

Windows

int connect(SOCKET sockfd, const struct sockaddr *serv_addr, int addrlen);?

作用

該函數(shù)用來向服務(wù)器發(fā)送連接請(qǐng)求

參數(shù)

sockfd

套接字描述符(客戶端的套接字)

serv_addr

要連接的服務(wù)器端的IP地址信息

addrlen

地址長度

返回值

成功

Linux

0

Windows

0

失敗

Linux

-1

Windows

SOCK_ERROR

2.7 send()和recv()

頭文件

Linux

#include <sys/socket.h>

Windows

#include <winsock2.h>

函數(shù)原型

Linux

int send(int sockfd,const void *buf,int len,int flags);

Windows

int send(SOCKET sockfd, const char *buf, int len, int flags);

作用

該函數(shù)用來發(fā)送數(shù)據(jù)

參數(shù)

sockfd

套接字描述符(客戶端的套接字)

buf

發(fā)送緩沖區(qū)的地址

len

發(fā)送數(shù)據(jù)的長度

flags

一般為0

返回值

成功

Linux

實(shí)際發(fā)送的字節(jié)數(shù)

Windows

實(shí)際發(fā)送的字節(jié)數(shù)

失敗

Linux

-1

Windows

SOCKET_ERROR

頭文件

Linux

#include <sys/socket.h>

Windows

#include <winsock2.h>

函數(shù)原型

Linux

int recv(int sockfd,void *buf,int len,unsigned int flags);

Windows

int recv(SOCKET sockfd, char *buf, int len, int flags);

作用

該函數(shù)用來接收數(shù)據(jù)

參數(shù)

sockfd

套接字描述符(客戶端的套接字描述符)

buf

存放接收數(shù)據(jù)的緩沖區(qū)地址

len

接收數(shù)據(jù)的長度

flags

一般為0

返回值

成功

Linux

實(shí)際接收到的字節(jié)數(shù)(收到EOF時(shí)為0)

Windows

實(shí)際接收到的字節(jié)數(shù)(收到EOF時(shí)為0)

失敗

Linux

-1

Windows

SOCKET_ERROR

2.8 sendto()和recvfrom()

這兩個(gè)函數(shù)一般在UDP通信過程中用于發(fā)送和接收數(shù)據(jù)。當(dāng)用在TCP時(shí),后面的幾個(gè)與地址有關(guān)的參數(shù)不起作用,函數(shù)作用等同于send()和recv()**

頭文件

#include <sys/socket.h>

函數(shù)原型

int sendto(int sockfd,const void *buf,int len, unsigned int flags,const struct sockaddr *to,int tolen);

作用

該函數(shù)用來發(fā)送數(shù)據(jù)

參數(shù)

sockfd

套接字描述符

buf

發(fā)送緩沖區(qū)的地址

len

發(fā)送數(shù)據(jù)的長度

flags

一般為0

to

接收方的套接字的IP地址和端口號(hào)

tolen

地址長度

返回值

成功

實(shí)際發(fā)送的字節(jié)數(shù)

失敗

-1

頭文件

#include <sys/socket.h>

函數(shù)原型

int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);

作用

該函數(shù)用來接收數(shù)據(jù)

參數(shù)

sockfd

套接字描述符

buf

存放接收數(shù)據(jù)的緩沖區(qū)地址

len

接收數(shù)據(jù)的長度

flags

一般為0

from

發(fā)送方的IP地址和端口號(hào)信息

Fromlen

地址長度

返回值

成功

實(shí)際接收到的字節(jié)數(shù)

失敗

-1

2.9 close()

頭文件

Linux

#include <sys/socket.h>

Windows

#include <winsock2.h>

函數(shù)原型

Linux

int close(int sockfd);

Windows

int closesocket(SOCKET sockfd);

作用

關(guān)閉套接字

參數(shù)

sockfd

套接字描述符

返回值

成功

Linux

0

Windows

0

失敗

Linux

-1

Windows

SOCKET_ERROR

3.代碼實(shí)現(xiàn)

3.1 server.cpp

#include<WINSOCK2.H>
#include<stdio.h>
#pragma comment(lib,"WS2_32.lib")
#define   BUFFER_SIZE 1024 //緩沖區(qū)大小
int main()
{WSADATA WSAData;SOCKET sClient;    //用于和客戶端socket進(jìn)行通信SOCKET sServer; //用于和本地地址綁定的socketint err_code; //存儲(chǔ)返回的錯(cuò)誤代碼char buffer[BUFFER_SIZE]; //緩沖區(qū)if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0){printf("WSAStartup failed,錯(cuò)誤代碼:%d\n",WSAGetLastError());return -1;}      //初始化winsocksServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //創(chuàng)建監(jiān)聽的socketif(sServer==INVALID_SOCKET){printf("創(chuàng)建Socket失敗,錯(cuò)誤代碼:%d\n",WSAGetLastError());WSACleanup();//清除初始化的Winsockreturn -1;}  SOCKADDR_IN addrServ;  //在監(jiān)聽的SOCKET綁定到本地之前,需要設(shè)置服務(wù)器Socket的地址addrServ.sin_family=AF_INET;addrServ.sin_port=htons(9990);//這里為什么不能用htonl()函數(shù)來轉(zhuǎn)換呢,因?yàn)镾OCKADDR_IN里面聲明的端口號(hào)為u_shortk類型addrServ.sin_addr.S_un.S_addr=htons(INADDR_ANY);//服務(wù)器監(jiān)聽端口為INADDR_ANY,即在任意本地地址(0.0.0.0)上進(jìn)行監(jiān)聽err_code=bind(sServer,(const sockaddr *)&addrServ,sizeof(SOCKADDR_IN));    //將用于綁定的sService綁定到本地地址if(err_code==SOCKET_ERROR){printf("bind failed,錯(cuò)誤代碼:%d\n",WSAGetLastError());closesocket(sServer);WSACleanup();return -1;}err_code=listen(sServer,1);  //監(jiān)聽客戶端socket,第一個(gè)參數(shù)為與本地地址綁定的socket,第二個(gè)參數(shù)表示等待連接隊(duì)列的最大長度if(err_code==SOCKET_ERROR){printf("listener failed,錯(cuò)誤代碼:%d\n",WSAGetLastError());closesocket(sServer);WSACleanup();return -1;}printf("TCP Server start...\n");sockaddr_in addrClient;int addrClientlen=sizeof(addrClient);sClient=accept(sServer,(sockaddr *)&addrClient,&addrClientlen);if(INVALID_SOCKET==sClient){printf("accept failed!,錯(cuò)誤代碼:%d\n",WSAGetLastError());closesocket(sServer);      WSACleanup();return -1;}//循環(huán)接收客戶端的數(shù)據(jù)while(true){ZeroMemory(buffer,BUFFER_SIZE);//初始化緩沖區(qū),把緩沖區(qū)置0err_code=recv(sClient,buffer,sizeof(buffer),0);if(err_code==SOCKET_ERROR){printf("Recv failed !,錯(cuò)誤代碼:%d\n",WSAGetLastError());closesocket(sClient);closesocket(sServer);WSACleanup();return -1;}if(strcmp(buffer,"quit")==0){ //當(dāng)客戶端發(fā)來quit時(shí),服務(wù)器就關(guān)閉send(sClient,"quit",strlen("quit"),0);break;}else{char msg[BUFFER_SIZE]="我是服務(wù)器,我已收到:";printf("接收來自客戶端[%s:%d]的消息 :%s\n",inet_ntoa(addrClient.sin_addr),addrClient.sin_port,buffer);strcat(msg,buffer);//拼接起來發(fā)送給主機(jī),表示服務(wù)器已收到消息err_code=send(sClient,msg,strlen(msg),0);if(err_code==SOCKET_ERROR){printf("send failed !錯(cuò)誤代碼:%d\n",WSAGetLastError());closesocket(sServer);closesocket(sClient);WSACleanup();return -1;}}}closesocket(sClient); //關(guān)閉用于通信的socketclosesocket(sServer);//關(guān)閉與本地地址綁定的socketWSACleanup();//釋放資源system("pause");return 0;
}

3.2 Client.cpp

#include<stdio.h>
#include<WINSOCK2.H>
#include<string.h>
#include<iphlpapi.h>
#pragma comment(lib,"WS2_32.lib")
#define BUFFER_SIZE 1024 //緩沖區(qū)大小
int main(){WSADATA WSAData;SOCKET s_Host;//本機(jī)socketsockaddr_in addrServer ;//服務(wù)器地址 char buf[BUFFER_SIZE]; //緩沖區(qū)字符數(shù)組int return_info;//存儲(chǔ)返回的錯(cuò)誤代碼if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0){ //初始化Winsock2.2printf("無法完成初始化,錯(cuò)誤代碼:%d",WSAGetLastError());WSACleanup();return 0;}s_Host=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if(s_Host==INVALID_SOCKET){printf("創(chuàng)建sockets失敗,錯(cuò)誤代碼:%d\n",WSAGetLastError());WSACleanup();return -1;}addrServer.sin_family=AF_INET;addrServer.sin_port=htons(9990);addrServer.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");return_info=connect(s_Host,(sockaddr*)&addrServer,sizeof(addrServer));if(SOCKET_ERROR==return_info){printf("連接服務(wù)器失敗,錯(cuò)誤代碼:%d",WSAGetLastError());closesocket(s_Host);WSACleanup();return -1;}//循環(huán)給服務(wù)器發(fā)送消息while(1){printf("請(qǐng)輸入要發(fā)送的消息:");gets(buf);return_info=send(s_Host,buf,strlen(buf),0);//這里用strlen()哦,用sizeof()就吧緩沖區(qū)那么大的數(shù)據(jù)傳過去了!!!if(return_info==SOCKET_ERROR){printf("發(fā)送消息失敗,錯(cuò)誤代碼:%d",WSAGetLastError());closesocket(s_Host);WSACleanup();return -1;}return_info= recv(s_Host,buf,sizeof(buf),0);    //recv()函數(shù)返回接收到的字節(jié)數(shù)if(return_info==SOCKET_ERROR){printf("接受服務(wù)器消息失敗, 錯(cuò)誤代碼:%d",WSAGetLastError());closesocket(s_Host);WSACleanup();return -1;}else{buf[return_info]='\0';}if(strcmp(buf,"quit")==0){//當(dāng)收到"quit"退出printf("退出...\n");break;}else{printf("%s\n",buf);}}if(WSACleanup()==SOCKET_ERROR){printf("WSACleanUp出錯(cuò)!!!");}  //做一些清除工作system("pause");return 0;
}
/*亂碼解決方案:
大部分編譯程序 在編譯的時(shí)候就把sizeof計(jì)算過了 是類型或是變量的長度這就是sizeof(x)可以用來定義數(shù)組維數(shù)的原因 
char str[20]="0123456789";
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;1.所以,在調(diào)用recv()函數(shù)時(shí),用sizeof(),因?yàn)閞ecv函數(shù)把接收緩沖中的數(shù)據(jù)copy到buf中
(注意協(xié)議接收到的數(shù)據(jù)可能大于buf的長度所以在這種情況下要調(diào)用幾次recv函數(shù)才能把s的接收緩沖中的數(shù)據(jù)copy完。
recv函數(shù)僅僅是copy數(shù)據(jù),真正的接收數(shù)據(jù)是協(xié)議來完成的),
recv函數(shù)返回其實(shí)際copy的字節(jié)數(shù)。如果recv在copy時(shí)出錯(cuò),
那么它返回SOCKET_ERROR;
如果recv函數(shù)在等待協(xié)議接收數(shù)據(jù)時(shí)網(wǎng)絡(luò)中斷了,那么它返回0。
2.在調(diào)用send()函數(shù)時(shí),用strlen(),因?yàn)檫@樣就會(huì)將輸入多少數(shù)據(jù),轉(zhuǎn)換為字節(jié)直接傳過去。而接受就不一樣了,接收的buf是緩沖區(qū)*/
http://m.risenshineclean.com/news/58436.html

相關(guān)文章:

  • 電子商務(wù)網(wǎng)站建設(shè)評(píng)估工具有哪些360搜索首頁
  • 西安網(wǎng)站建設(shè)市場(chǎng)虛擬主機(jī)搭建網(wǎng)站
  • 臨安建設(shè)投標(biāo)網(wǎng)站教育培訓(xùn)機(jī)構(gòu)有哪些
  • 新網(wǎng)站做seo地方網(wǎng)站建設(shè)
  • pc端移動(dòng)端網(wǎng)站開發(fā)太原網(wǎng)站快速排名提升
  • 濰坊網(wǎng)站制作 熊掌號(hào)臨汾網(wǎng)絡(luò)推廣
  • 為什么做網(wǎng)站更新注冊(cè)網(wǎng)站域名
  • 好域名做網(wǎng)站手機(jī)免費(fèi)發(fā)布信息平臺(tái)
  • 惠州市做網(wǎng)站網(wǎng)絡(luò)營銷的內(nèi)涵
  • 汨羅網(wǎng)站建設(shè)制作網(wǎng)站平臺(tái)
  • 如何外貿(mào)seo網(wǎng)站建設(shè)外鏈工具
  • 博物館網(wǎng)站建設(shè)方案報(bào)價(jià)關(guān)鍵詞優(yōu)化分析工具
  • 公司宣傳冊(cè)設(shè)計(jì)與制作模板seo免費(fèi)課程
  • 在美國注冊(cè)一個(gè)網(wǎng)站 大陸做銷售網(wǎng)址推薦
  • 自己做網(wǎng)站現(xiàn)實(shí)么網(wǎng)站設(shè)計(jì)就業(yè)
  • 沒網(wǎng)站能不能cpc廣告點(diǎn)擊賺錢做關(guān)鍵詞優(yōu)化排名的步驟
  • 開發(fā)網(wǎng)頁系統(tǒng)一般多少錢windows優(yōu)化大師官網(wǎng)
  • 中學(xué)生旅游網(wǎng)站開發(fā)的論文怎么寫外鏈seo推廣
  • 都昌網(wǎng)站建設(shè)seo可以從哪些方面優(yōu)化
  • 企業(yè)網(wǎng)站推廣設(shè)計(jì)網(wǎng)站優(yōu)化推廣
  • 個(gè)人網(wǎng)站怎么做支付寶接口google推廣妙招
  • wordpress主題生成seo這個(gè)行業(yè)怎么樣
  • 做爰網(wǎng)站美女東莞今日頭條最新消息
  • 網(wǎng)站建設(shè)怎么樣真正免費(fèi)建站
  • 網(wǎng)站做推廣需要多少錢seo博客優(yōu)化
  • 網(wǎng)站建設(shè)畢業(yè)設(shè)計(jì)中期檢查自己怎么創(chuàng)建一個(gè)網(wǎng)站
  • 重慶網(wǎng)站建設(shè)公司模板地推掃碼平臺(tái)
  • 找電商平臺(tái)幫我賣產(chǎn)品網(wǎng)站優(yōu)化排名工具
  • 鷹潭市城鄉(xiāng)建設(shè)局網(wǎng)站seo實(shí)戰(zhàn)密碼第四版
  • ASP動(dòng)態(tài)商業(yè)網(wǎng)站建設(shè)案例山西seo優(yōu)化公司