www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 嵌入式 > 嵌入式教程
[導(dǎo)讀]在Linux中的網(wǎng)絡(luò)編程是通過socket接口來進(jìn)行的。人們常說的socket是一種特殊的I/O接口,它也是一種文件描述符。socket是一種常用的進(jìn)程之間通信機(jī)制,通過它不僅能實(shí)現(xiàn)本地機(jī)器上的進(jìn)程之間的通信,而且通過網(wǎng)絡(luò)能夠在不同機(jī)器上的進(jìn)程之間進(jìn)行通信。

10.2網(wǎng)絡(luò)基礎(chǔ)編程10.2.1socket概述1.socket定義

在Linux中的網(wǎng)絡(luò)編程是通過socket接口來進(jìn)行的。人們常說的socket是一種特殊的I/O接口,它也是一種文件描述符。socket是一種常用的進(jìn)程之間通信機(jī)制,通過它不僅能實(shí)現(xiàn)本地機(jī)器上的進(jìn)程之間的通信,而且通過網(wǎng)絡(luò)能夠在不同機(jī)器上的進(jìn)程之間進(jìn)行通信。

每一個socket都用一個半相關(guān)描述{協(xié)議、本地地址、本地端口}來表示;一個完整的套接字則用一個相關(guān)描述{協(xié)議、本地地址、本地端口、遠(yuǎn)程地址、遠(yuǎn)程端口}來表示。socket也有一個類似于打開文件的函數(shù)調(diào)用,該函數(shù)返回一個整型的socket描述符,隨后的連接建立、數(shù)據(jù)傳輸?shù)炔僮鞫际峭ㄟ^socket來實(shí)現(xiàn)的。

2.socket類型

常見的socket有3種類型如下。

(1)流式socket(SOCK_STREAM)。

流式套接字提供可靠的、面向連接的通信流;它使用TCP協(xié)議,從而保證了數(shù)據(jù)傳輸?shù)恼_性和順序性。

(2)數(shù)據(jù)報(bào)socket(SOCK_DGRAM)。

數(shù)據(jù)報(bào)套接字定義了一種無連接的服務(wù),數(shù)據(jù)通過相互獨(dú)立的報(bào)文進(jìn)行傳輸,是無序的,并且不保證是可靠、無差錯的。它使用數(shù)據(jù)報(bào)協(xié)議UDP。

(3)原始socket。

原始套接字允許對底層協(xié)議如IP或ICMP進(jìn)行直接訪問,它功能強(qiáng)大但使用較為不便,主要用于一些協(xié)議的開發(fā)。

10.2.2地址及順序處理1.地址結(jié)構(gòu)相關(guān)處理

(1)數(shù)據(jù)結(jié)構(gòu)介紹。

下面首先介紹兩個重要的數(shù)據(jù)類型:sockaddr和sockaddr_in,這兩個結(jié)構(gòu)類型都是用來保存socket信息的,如下所示:

structsockaddr

{

unsignedshortsa_family;/*地址族*/

charsa_data[14];/*14字節(jié)的協(xié)議地址,包含該socket的IP地址和端口號。*/

};

structsockaddr_in

{

shortintsa_family;/*地址族*/

unsignedshortintsin_port;/*端口號*/

structin_addrsin_addr;/*IP地址*/

unsignedcharsin_zero[8];/*填充0以保持與structsockaddr同樣大小*/

};

這兩個數(shù)據(jù)類型是等效的,可以相互轉(zhuǎn)化,通常sockaddr_in數(shù)據(jù)類型使用更為方便。在建立socketadd或sockaddr_in后,就可以對該socket進(jìn)行適當(dāng)?shù)牟僮髁恕?/p>

(2)結(jié)構(gòu)字段。

表10.1列出了該結(jié)構(gòu)sa_family字段可選的常見值。

表10.1

結(jié)構(gòu)定義頭文件

#include<netinet/in.h>

sa_family

AF_INET:IPv4協(xié)議

AF_INET6:IPv6協(xié)議

AF_LOCAL:UNIX域協(xié)議

AF_LINK:鏈路地址協(xié)議

AF_KEY:密鑰套接字(socket)

sockaddr_in其他字段的含義非常清楚,具體的設(shè)置涉及其他函數(shù),在后面會有詳細(xì)的講解。

2.?dāng)?shù)據(jù)存儲優(yōu)先順序

(1)函數(shù)說明。

計(jì)算機(jī)數(shù)據(jù)存儲有兩種字節(jié)優(yōu)先順序:高位字節(jié)優(yōu)先(稱為大端模式)和低位字節(jié)優(yōu)先(稱為小端模式,PC機(jī)通常采用小端模式)。Internet上數(shù)據(jù)以高位字節(jié)優(yōu)先順序在網(wǎng)絡(luò)上傳輸,因此在有些情況下,需要對這兩個字節(jié)存儲優(yōu)先順序進(jìn)行相互轉(zhuǎn)化。這里用到了4個函數(shù):htons()、ntohs()、htonl()和ntohl()。這4個地址分別實(shí)現(xiàn)網(wǎng)絡(luò)字節(jié)序和主機(jī)字節(jié)序的轉(zhuǎn)化,這里的h代表host,n代表network,s代表short,l代表long。通常16位的IP端口號用s代表,而IP地址用l來代表。

(2)函數(shù)格式說明。

表10.2列出了這4個函數(shù)的語法格式。

表10.2 htons等函數(shù)語法要點(diǎn)

所需頭文件

#include<netinet/in.h>

函數(shù)原型

uint16_thtons(unit16_thost16bit)
uint32_thtonl(unit32_thost32bit)
uint16_tntohs(unit16_tnet16bit)
uint32_tntohs(unit32_tnet32bit)

函數(shù)傳入值

host16bit:主機(jī)字節(jié)序的16位數(shù)據(jù)

host32bit:主機(jī)字節(jié)序的32位數(shù)據(jù)

net16bit:網(wǎng)絡(luò)字節(jié)序的16位數(shù)據(jù)

net32bit:網(wǎng)絡(luò)字節(jié)序的32位數(shù)據(jù)

函數(shù)返回值

成功:返回要轉(zhuǎn)換的字節(jié)序

出錯:-1

注意

調(diào)用該函數(shù)只是使其得到相應(yīng)的字節(jié)序,用戶不需清楚該系統(tǒng)的主機(jī)字節(jié)序和網(wǎng)絡(luò)字節(jié)序是否真正相等。如果是相同不需要轉(zhuǎn)換的話,該系統(tǒng)的這些函數(shù)會定義成空宏。

3.地址格式轉(zhuǎn)化

(1)函數(shù)說明。

通常用戶在表達(dá)地址時采用的是點(diǎn)分十進(jìn)制表示的數(shù)值(或者是以冒號分開的十進(jìn)制IPv6地址),而在通常使用的socket編程中所使用的則是二進(jìn)制值,這就需要將這兩個數(shù)值進(jìn)行轉(zhuǎn)換。這里在IPv4中用到的函數(shù)有inet_aton()、inet_addr()和inet_ntoa(),而IPv4和IPv6兼容的函數(shù)有inet_pton()和inet_ntop()。由于IPv6是下一代互聯(lián)網(wǎng)的標(biāo)準(zhǔn)協(xié)議,因此,本書講解的函數(shù)都能夠同時兼容IPv4和IPv6,但在具體舉例時仍以IPv4為例。

這里inet_pton()函數(shù)是將點(diǎn)分十進(jìn)制地址映射為二進(jìn)制地址,而inet_ntop()是將二進(jìn)制地址映射為點(diǎn)分十進(jìn)制地址。

(2)函數(shù)格式。

表10.3列出了inet_pton函數(shù)的語法要點(diǎn)。

表10.3 inet_pton函數(shù)語法要點(diǎn)

所需頭文件

#include<arpa/inet.h>

函數(shù)原型

intinet_pton(intfamily,constchar*strptr,void*addrptr)

函數(shù)傳入值

family

AF_INET:IPv4協(xié)議

AF_INET6:IPv6協(xié)議

strptr:要轉(zhuǎn)化的值

addrptr:轉(zhuǎn)化后的地址

函數(shù)返回值

成功:0

出錯:-1

表10.4列出了inet_ntop函數(shù)的語法要點(diǎn)。

表10.4 inet_ntop函數(shù)語法要點(diǎn)

所需頭文件

#include<arpa/inet.h>

函數(shù)原型

intinet_ntop(intfamily,void*addrptr,char*strptr,size_tlen)

函數(shù)傳入值

family

AF_INET:IPv4協(xié)議

AF_INET6:IPv6協(xié)議

函數(shù)傳入值

addrptr:轉(zhuǎn)化后的地址

strptr:要轉(zhuǎn)化的值

len:轉(zhuǎn)化后值的大小

函數(shù)返回值

成功:0

出錯:-1

4.名字地址轉(zhuǎn)化

(1)函數(shù)說明。

通常,人們在使用過程中都不愿意記憶冗長的IP地址,尤其到IPv6時,地址長度多達(dá)128位,那時就更加不可能一次次記憶那么長的IP地址了。因此,使用主機(jī)名將會是很好的選擇。在Linux中,同樣有一些函數(shù)可以實(shí)現(xiàn)主機(jī)名和地址的轉(zhuǎn)化,最為常見的有g(shù)ethostbyname()、gethostbyaddr()和getaddrinfo()等,它們都可以實(shí)現(xiàn)IPv4和IPv6的地址和主機(jī)名之間的轉(zhuǎn)化。其中g(shù)ethostbyname()是將主機(jī)名轉(zhuǎn)化為IP地址,gethostbyaddr()則是逆操作,是將IP地址轉(zhuǎn)化為主機(jī)名,另外getaddrinfo()還能實(shí)現(xiàn)自動識別IPv4地址和IPv6地址。

gethostbyname()和gethostbyaddr()都涉及一個hostent的結(jié)構(gòu)體,如下所示:

structhostent

{

char*h_name;/*正式主機(jī)名*/

char**h_aliases;/*主機(jī)別名*/

inth_addrtype;/*地址類型*/

inth_length;/*地址字節(jié)長度*/

char**h_addr_list;/*指向IPv4或IPv6的地址指針數(shù)組*/

}

調(diào)用gethostbyname()函數(shù)或gethostbyaddr()函數(shù)后就能返回hostent結(jié)構(gòu)體的相關(guān)信息。

getaddrinfo()函數(shù)涉及一個addrinfo的結(jié)構(gòu)體,如下所示:

structaddrinfo

{

intai_flags;/*AI_PASSIVE,AI_CANONNAME;*/

intai_family;/*地址族*/

intai_socktype;/*socket類型*/

intai_protocol;/*協(xié)議類型*/

size_tai_addrlen;/*地址字節(jié)長度*/

char*ai_canonname;/*主機(jī)名*/

structsockaddr*ai_addr;/*socket結(jié)構(gòu)體*/

structaddrinfo*ai_next;/*下一個指針鏈表*/

}

hostent結(jié)構(gòu)體而言,addrinfo結(jié)構(gòu)體包含更多的信息。

(2)函數(shù)格式。

表10.5列出了gethostbyname()函數(shù)的語法要點(diǎn)。

表10.5 gethostbyname函數(shù)語法要點(diǎn)

所需頭文件

#include<netdb.h>

函數(shù)原型

structhostent*gethostbyname(constchar*hostname)

函數(shù)傳入值

hostname:主機(jī)名

函數(shù)返回值

成功:hostent類型指針

出錯:-1

調(diào)用該函數(shù)時可以首先對hostent結(jié)構(gòu)體中的h_addrtype和h_length進(jìn)行設(shè)置,若為IPv4可設(shè)置為AF_INET和4;若為IPv6可設(shè)置為AF_INET6和16;若不設(shè)置則默認(rèn)為IPv4地址類型。

表10.6列出了getaddrinfo()函數(shù)的語法要點(diǎn)。

表10.6 getaddrinfo()函數(shù)語法要點(diǎn)

所需頭文件

#include<netdb.h>

函數(shù)原型

intgetaddrinfo(constchar*node,constchar*service,conststructaddrinfo*hints,structaddrinfo**result)

函數(shù)傳入值

node:網(wǎng)絡(luò)地址或者網(wǎng)絡(luò)主機(jī)名

service:服務(wù)名或十進(jìn)制的端口號字符串

hints:服務(wù)線索

result:返回結(jié)果

函數(shù)返回值

成功:0

出錯:-1

在調(diào)用之前,首先要對hints服務(wù)線索進(jìn)行設(shè)置。它是一個addrinfo結(jié)構(gòu)體,表10.7列舉了該結(jié)構(gòu)體常見的選項(xiàng)值。

表10.7 addrinfo結(jié)構(gòu)體常見選項(xiàng)值

結(jié)構(gòu)體頭文件

#include<netdb.h>

ai_flags

AI_PASSIVE:該套接口是用作被動地打開

AI_CANONNAME:通知getaddrinfo函數(shù)返回主機(jī)的名字

ai_family

AF_INET:IPv4協(xié)議

AF_INET6:IPv6協(xié)議

AF_UNSPEC:IPv4或IPv6均可

ai_socktype

SOCK_STREAM:字節(jié)流套接字socket(TCP)

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

ai_protocol

IPPROTO_IP:IP協(xié)議

IPPROTO_IPV4:IPv4協(xié)議

4

IPv4

IPPROTO_IPV6:IPv6協(xié)議

IPPROTO_UDP:UDP

IPPROTO_TCP:TCP

注意

(1)通常服務(wù)器端在調(diào)用getaddrinfo()之前,ai_flags設(shè)置AI_PASSIVE,用于bind()函數(shù)(用于端口和地址的綁定,后面會講到),主機(jī)名nodename通常會設(shè)置為NULL。

(2)客戶端調(diào)用getaddrinfo()時,ai_flags一般不設(shè)置AI_PASSIVE,但是主機(jī)名nodename和服務(wù)名servname(端口)則應(yīng)該不為空。

(3)即使不設(shè)置ai_flags為AI_PASSIVE,取出的地址也可以被綁定,很多程序中ai_flags直接設(shè)置為0,即3個標(biāo)志位都不設(shè)置,這種情況下只要hostname和servname設(shè)置的沒有問題就可以正確綁定。

(3)使用實(shí)例。

下面的實(shí)例給出了getaddrinfo函數(shù)用法的示例,在后面小節(jié)中會給出gethostbyname函數(shù)用法的例子。

/*getaddrinfo.c*/

#include<stdio.h>

#include<stdlib.h>

#include<errno.h>

#include<string.h>

#include<netdb.h>

#include<sys/types.h>

#include<netinet/in.h>

#include<sys/socket.h>

intmain()

{

structaddrinfohints,*res=NULL;

intrc;

memset(&hints,0,sizeof(hints));

/*設(shè)置addrinfo結(jié)構(gòu)體中各參數(shù)*/

hints.ai_flags=AI_CANONNAME;

hints.ai_family=AF_UNSPEC;

hints.ai_socktype=SOCK_DGRAM;

hints.ai_protocol=IPPROTO_UDP;

/*調(diào)用getaddinfo函數(shù)*/

rc=getaddrinfo("localhost",NULL,&hints,&res);

if(rc!=0)

{

perror("getaddrinfo");

exit(1);

}

else

{

printf("Hostnameis%sn",res->ai_canonname);

}

exit(0);

}

10.2.3socket基礎(chǔ)編程

(1)函數(shù)說明。

socket編程的基本函數(shù)有socket()、bind()、listen()、accept()、send()、sendto()、recv()以及recvfrom()等,其中根據(jù)客戶端還是服務(wù)端,或者根據(jù)使用TCP協(xié)議還是UDP協(xié)議,這些函數(shù)的調(diào)用流程都有所區(qū)別,這里先對每個函數(shù)進(jìn)行說明,再給出各種情況下使用的流程圖。

n socket():該函數(shù)用于建立一個socket連接,可指定socket類型等信息。在建立了socket連接之后,可對sockaddr或sockaddr_in結(jié)構(gòu)進(jìn)行初始化,以保存所建立的socket地址信息。

n bind():該函數(shù)是用于將本地IP地址綁定到端口號,若綁定其他IP地址則不能成功。另外,它主要用于TCP的連接,而在UDP的連接中則無必要。

n listen():在服務(wù)端程序成功建立套接字和與地址進(jìn)行綁定之后,還需要準(zhǔn)備在該套接字上接收新的連接請求。此時調(diào)用listen()函數(shù)來創(chuàng)建一個等待隊(duì)列,在其中存放未處理的客戶端連接請求。

n accept():服務(wù)端程序調(diào)用listen()函數(shù)創(chuàng)建等待隊(duì)列之后,調(diào)用accept()函數(shù)等待并接收客戶端的連接請求。它通常從由bind()所創(chuàng)建的等待隊(duì)列中取出第一個未處理的連接請求。

n connect():該函數(shù)在TCP中是用于bind()的之后的client端,用于與服務(wù)器端建立連接,而在UDP中由于沒有了bind()函數(shù),因此用connect()有點(diǎn)類似bind()函數(shù)的作用。

n send()和recv():這兩個函數(shù)分別用于發(fā)送和接收數(shù)據(jù),可以用在TCP中,也可以用在UDP中。當(dāng)用在UDP時,可以在connect()函數(shù)建立連接之后再用。

n sendto()和recvfrom():這兩個函數(shù)的作用與send()和recv()函數(shù)類似,也可以用在TCP和UDP中。當(dāng)用在TCP時,后面的幾個與地址有關(guān)參數(shù)不起作用,函數(shù)作用等同于send()和recv();當(dāng)用在UDP時,可以用在之前沒有使用connect()的情況下,這兩個函數(shù)可以自動尋找指定地址并進(jìn)行連接。

服務(wù)器端和客戶端使用TCP協(xié)議的流程如圖10.6所示。

服務(wù)器端和客戶端使用UDP協(xié)議的流程如圖10.7所示。

圖10.6使用TCP協(xié)議socket編程流程圖圖10.7使用UDP協(xié)議socket編程流程圖

(2)函數(shù)格式。

表10.8列出了socket()函數(shù)的語法要點(diǎn)。

表10.8 socket()函數(shù)語法要點(diǎn)

所需頭文件

#include<sys/socket.h>

函數(shù)原型

intsocket(intfamily,inttype,intprotocol)

函數(shù)傳入值

family:

協(xié)議族

AF_INET:IPv4協(xié)議

AF_INET6:IPv6協(xié)議

AF_LOCAL:UNIX域協(xié)議

AF_ROUTE:路由套接字(socket)

AF_KEY:密鑰套接字(socket)

type:

套接字類型

SOCK_STREAM:字節(jié)流套接字socket

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

SOCK_RAW:原始套接字socket

protoco:0(原始套接字除外)

函數(shù)返回值

成功:非負(fù)套接字描述符

出錯:-1

表10.9列出了bind()函數(shù)的語法要點(diǎn)。

表10.9 bind()函數(shù)語法要點(diǎn)

所需頭文件

#include<sys/socket.h>

函數(shù)原型

intbind(intsockfd,structsockaddr*my_addr,intaddrlen)

函數(shù)傳入值

socktd:套接字描述符

my_addr:本地地址

addrlen:地址長度

函數(shù)返回值

成功:0

出錯:-1

端口號和地址在my_addr中給出了,若不指定地址,則內(nèi)核隨意分配一個臨時端口給該應(yīng)用程序。

表10.10列出了listen()函數(shù)的語法要點(diǎn)。

表10.10 listen()函數(shù)語法要點(diǎn)

所需頭文件

#include<sys/socket.h>

函數(shù)原型

intlisten(intsockfd,intbacklog)

函數(shù)傳入值

socktd:套接字描述符

backlog:請求隊(duì)列中允許的最大請求數(shù),大多數(shù)系統(tǒng)缺省值為5

函數(shù)返回值

成功:0

出錯:-1

表10.11列出了accept()函數(shù)的語法要點(diǎn)。

表10.11 accept()函數(shù)語法要點(diǎn)

所需頭文件

#include<sys/socket.h>

函數(shù)原型

intaccept(intsockfd,structsockaddr*addr,socklen_t*addrlen)

函數(shù)傳入值

socktd:套接字描述符

addr:客戶端地址

addrlen:地址長度

函數(shù)返回值

成功:0

出錯:-1

表10.12列出了connect()函數(shù)的語法要點(diǎn)。

表10.12 connect()函數(shù)語法要點(diǎn)

所需頭文件

#include<sys/socket.h>

函數(shù)原型

intconnect(intsockfd,structsockaddr*serv_addr,intaddrlen)

函數(shù)傳入值

socktd:套接字描述符

serv_addr:服務(wù)器端地址

addrlen:地址長度

函數(shù)返回值

成功:0

出錯:-1

表10.13列出了send()函數(shù)的語法要點(diǎn)。

表10.13 send()函數(shù)語法要點(diǎn)

所需頭文件

#include<sys/socket.h>

函數(shù)原型

intsend(intsockfd,constvoid*msg,intlen,intflags)

函數(shù)傳入值

socktd:套接字描述符

msg:指向要發(fā)送數(shù)據(jù)的指針

len:數(shù)據(jù)長度

flags:一般為0

函數(shù)返回值

成功:發(fā)送的字節(jié)數(shù)

出錯:-1

表10.14列出了recv()函數(shù)的語法要點(diǎn)。

表10.14 recv()函數(shù)語法要點(diǎn)

所需頭文件

#include<sys/socket.h>

函數(shù)原型

intrecv(intsockfd,void*buf,intlen,unsignedintflags)

函數(shù)傳入值

socktd:套接字描述符

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

len:數(shù)據(jù)長度

flags:一般為0

函數(shù)返回值

成功:接收的字節(jié)數(shù)

出錯:-1

表10.15列出了sendto()函數(shù)的語法要點(diǎn)。

表10.15 sendto()函數(shù)語法要點(diǎn)

所需頭文件

#include<sys/socket.h>

函數(shù)原型

intsendto(intsockfd,constvoid*msg,intlen,unsignedintflags,conststructsockaddr*to,inttolen)

函數(shù)傳入值

socktd:套接字描述符

msg:指向要發(fā)送數(shù)據(jù)的指針

len:數(shù)據(jù)長度

flags:一般為0

to:目地機(jī)的IP地址和端口號信息

tolen:地址長度

函數(shù)返回值

成功:發(fā)送的字節(jié)數(shù)

出錯:-1

表10.16列出了recvfrom()函數(shù)的語法要點(diǎn)。

表10.16 recvfrom()函數(shù)語法要點(diǎn)

所需頭文件

#include<sys/socket.h>

函數(shù)原型

intrecvfrom(intsockfd,void*buf,intlen,unsignedintflags,structsockaddr*from,int*fromlen)

函數(shù)傳入值

socktd:套接字描述符

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

len:數(shù)據(jù)長度

flags:一般為0

from:源主機(jī)的IP地址和端口號信息

tolen:地址長度

函數(shù)返回值

成功:接收的字節(jié)數(shù)

出錯:-1

(3)使用實(shí)例。

該實(shí)例分為客戶端和服務(wù)器端兩部分,其中服務(wù)器端首先建立起socket,然后與本地端口進(jìn)行綁定,接著就開始接收從客戶端的連接請求并建立與它的連接,接下來,接收客戶端發(fā)送的消息??蛻舳藙t在建立socket之后調(diào)用connect()函數(shù)來建立連接。

服務(wù)端的代碼如下所示:

/*server.c*/

#include<sys/types.h>

#include<sys/socket.h>

#include<stdio.h>

#include<stdlib.h>

#include<errno.h>

#include<string.h>

#include<unistd.h>

#include<netinet/in.h>

#definePORT4321

#defineBUFFER_SIZE1024

#defineMAX_QUE_CONN_NM5

intmain()

{

structsockaddr_inserver_sockaddr,client_sockaddr;

intsin_size,recvbytes;

intsockfd,client_fd;

charbuf[BUFFER_SIZE];

/*建立socket連接*/

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

{

perror("socket");

exit(1);

}

printf("Socketid=%dn",sockfd);

/*設(shè)置sockaddr_in結(jié)構(gòu)體中相關(guān)參數(shù)*/

server_sockaddr.sin_family=AF_INET;

server_sockaddr.sin_port=htons(PORT);

server_sockaddr.sin_addr.s_addr=INADDR_ANY;

bzero(&(server_sockaddr.sin_zero),8);

inti=1;/*允許重復(fù)使用本地地址與套接字進(jìn)行綁定*/

setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));

/*綁定函數(shù)bind()*/

if(bind(sockfd,(structsockaddr*)&server_sockaddr,

sizeof(structsockaddr))==-1)

{

perror("bind");

exit(1);

}

printf("Bindsuccess!n");

/*調(diào)用listen()函數(shù),創(chuàng)建未處理請求的隊(duì)列*/

if(listen(sockfd,MAX_QUE_CONN_NM)==-1)

{

perror("listen");

exit(1);

}

printf("Listening....n");

/*調(diào)用accept()函數(shù),等待客戶端的連接*/

if((client_fd=accept(sockfd,

(structsockaddr*)&client_sockaddr,&sin_size))==-1)

{

perror("accept");

exit(1);

}

/*調(diào)用recv()函數(shù)接收客戶端的請求*/

memset(buf,0,sizeof(buf));

if((recvbytes=recv(client_fd,buf,BUFFER_SIZE,0))==-1)

{

perror("recv");

exit(1);

}

printf("Receivedamessage:%sn",buf);

close(sockfd);

exit(0);

}

客戶端的代碼如下所示:

/*client.c*/

#include<stdio.h>

#include<stdlib.h>

#include<errno.h>

#include<string.h>

#include<netdb.h>

#include<sys/types.h>

#include<netinet/in.h>

#include<sys/socket.h>

#definePORT4321

#defineBUFFER_SIZE1024

intmain(intargc,char*argv[])

{

intsockfd,sendbytes;

charbuf[BUFFER_SIZE];

structhostent*host;

structsockaddr_inserv_addr;

if(argc<3)

{

fprintf(stderr,"USAGE:./clientHostname(oripaddress)Textn");

exit(1);

}

/*地址解析函數(shù)*/

if((host=gethostbyname(argv[1]))==NULL)

{

perror("gethostbyname");

exit(1);

}

memset(buf,0,sizeof(buf));

sprintf(buf,"%s",argv[2]);

/*創(chuàng)建socket*/

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

{

perror("socket");

exit(1);

}

/*設(shè)置sockaddr_in結(jié)構(gòu)體中相關(guān)參數(shù)*/

serv_addr.sin_family=AF_INET;

serv_addr.sin_port=htons(PORT);

serv_addr.sin_addr=*((structin_addr*)host->h_addr);

bzero(&(serv_addr.sin_zero),8);

/*調(diào)用connect函數(shù)主動發(fā)起對服務(wù)器端的連接*/

if(connect(sockfd,(structsockaddr*)&serv_addr,

sizeof(structsockaddr))==-1)

{

perror("connect");

exit(1);

}

/*發(fā)送消息給服務(wù)器端*/

if((sendbytes=send(sockfd,buf,strlen(buf),0))==-1)

{

perror("send");

exit(1);

}

close(sockfd);

exit(0);

}

在運(yùn)行時需要先啟動服務(wù)器端,再啟動客戶端。這里可以把服務(wù)器端下載到開發(fā)板上,客戶端在宿主機(jī)上運(yùn)行,然后配置雙方的IP地址,在確保雙方可以通信(如使用ping命令驗(yàn)證)的情況下運(yùn)行該程序即可。

$./server

Socketid=3

Bindsuccess!

Listening....

Receivedamessage:Hello,Server!

$./clientlocalhost(或者輸入IP地址)Hello,Server!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉