Linux网络编程之TCPWord文档下载推荐.docx

上传人:b****5 文档编号:19787823 上传时间:2023-01-10 格式:DOCX 页数:24 大小:24.37KB
下载 相关 举报
Linux网络编程之TCPWord文档下载推荐.docx_第1页
第1页 / 共24页
Linux网络编程之TCPWord文档下载推荐.docx_第2页
第2页 / 共24页
Linux网络编程之TCPWord文档下载推荐.docx_第3页
第3页 / 共24页
Linux网络编程之TCPWord文档下载推荐.docx_第4页
第4页 / 共24页
Linux网络编程之TCPWord文档下载推荐.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

Linux网络编程之TCPWord文档下载推荐.docx

《Linux网络编程之TCPWord文档下载推荐.docx》由会员分享,可在线阅读,更多相关《Linux网络编程之TCPWord文档下载推荐.docx(24页珍藏版)》请在冰豆网上搜索。

Linux网络编程之TCPWord文档下载推荐.docx

u32s_addr;

//32位地址

};

(2)相关函数

#include<

sys/socket.h>

sys/types.h>

intsocket(intdomain,inttype,intprotocol);

参数:

domain-通信的域,AF_INET表示IPV4协议,PF_INET6表示IPV6协议

type-设置套接字通信的类型SOCK_STREAM流式套接字,SOCK_DGRAM数据报套接字,SOCK_RAW原始套接字

protocol-表示某个通信类型的特定类型,如果type只有一个类型,那么这个参数设置为0

返回值:

成功返回套接字描述符,失败返回-1

#include<

intbind(intsockfd,conststructsockaddr*my_addr,socket_taddrlen);

sockfd-套接字描述符

my_addr-sockaddr指针类型,指向一个套接字的地址结构

addrlen-地址结构的长度

成功绑定返回0,失败绑定返回-1

intlisten(intsockfd,intbacklog);

backlog-等待队列的长度

成功返回0,失败返回-1

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

addr-指向地址结构的指针

addrlen-地址结构的长度指针

其中addr包含的是客户端的地址结构,包括客户端的IP,端口号,协议族等等.

成功返回的是用于服务器与客户端通信的套接字描述符,失败返回-1

intconnect(intsockfd,structsockaddr*addr,intaddrlen);

sockfd-客户端套接字描述符

addr-需要连接的服务器的地址结构

addrlen-服务器的地址结构的长度

连接成功返回0,失败返回-1

close(ints);

s-套接字描述符

成功关闭套接字返回0,失败返回-1

3.TCP通信的实例

服务器端:

stdio.h>

stdlib.h>

strings.h>

unistd.h>

linux/in.h>

#definePORT8888

#defineBACKLOG2

//服务器端程序

/**

(1)建立一个套接字描述符,定义网络类型,协议类型和具体的协议标号socket()

(2)将套接字与具体的地址结构绑定,这个地址结构包括端口号,IP地址,网络类型bind()

(3)侦听客户端发出的请求,设置队列的长度listen()

(4)在客户端发出请求后,处理客户端的连接,返回一个新的套接字描述符用于服务器端与客户端的通信accept()

(5)读写数据read()vs.write()

(6)当服务器处理完数据要结构通信过程,关闭连接close()

**/

voidprocess(intsc);

intmain(intargc,char*argv[]){

intss,sc;

//ss为服务器端的套接字描述符,sc为客户端的套接字描述符,即返回的新的套接字描述符

structsockaddr_inserver_addr;

//服务器端的地址结构

structsockaddr_inclient_addr;

//客户端的地址结构

interr;

//返回值

pid_tpid;

//进程的pid

//建立一个流式套接字

ss=socket(AF_INET,SOCK_STREAM,0);

//第一个参数用来设置通信的域,AF_INET表示使用IPv4Internet协议,第二个参数是套接字通信的类型,表示流式套接字,第三个参数表示某种协议的特定类型,如果只有一种类型,设置为0

if(ss<

0){

printf("

socketerror\n"

);

return-1;

//设置服务器的地址结构

bzero(&

server_addr,sizeof(server_addr));

//清0

server_addr.sin_family=AF_INET;

//通信的域,通常与socket函数的domain一致

server_addr.sin_addr.s_addr=htonl(INADDR_ANY);

//本地地址

server_addr.sin_port=htons(PORT);

//服务器端口

//绑定地址结构到套接字描述符

err=bind(ss,(structsockaddr*)&

//第一个参数是套接字描述符,第二个参数是sockaddr指针,第三个参数是server_addr的长度

if(err<

0){

perror("

binderror"

//设置侦听

err=listen(ss,BACKLOG);

//第一个参数是服务器端的套接字描述符,第二个参数是侦听队列的长度

listenerror"

for(;

;

){

intaddrlen=sizeof(structsockaddr);

//接收客户端的连接

sc=accept(ss,(structsockaddr*)&

client_addr,&

addrlen);

//第一个参数是服务器端的套接字描述符,第二个参数是sockaddr结构体指针,第三个参数是sockaddr长度的指针

if(sc<

continue;

//客户端的信息存储在sockaddr结构体

intsin_port=client_addr.sin_port;

//返回连接的客户端端口号

portis%d\n"

sin_port);

//建立一个子进程来处理连接

pid=fork();

if(pid==0){//子进程

close(ss);

//关闭服务器的侦听

process(sc);

//处理连接,用返回的新的客户端描述符来处理连接

}else{

close(sc);

//在父进程关闭客户端的连接

voidprocess(intsc){

ssize_tsize=0;

charbuffer[1024];

for(;

size=read(sc,buffer,1024);

//返回读取的字节数

if(size==0)

return;

write(1,buffer,size);

//终端输出

sprintf(buffer,"

%dbytes\n"

size);

write(sc,buffer,strlen(buffer)+1);

//发送给客户端

}

客户端:

(1)建立套接字描述符

(2)connect与服务器端三次握手,连接服务器端

(3)readvswrite

(4)关闭连接

voidprocess(ints);

ints;

//服务器端的地址结构

s=socket(AF_INET,SOCK_STREAM,0);

//建立一个套接字描述符,参数1表示通信的域IPv4协议,参数2表示通信类型流式套接字,参数3表示某种协议的特定类型如果只有一种类型为0

if(s<

//设置服务器地址

//本地地址,可接受任意IP

inet_pton(AF_INET,argv[1],&

server_addr.sin_addr);

//用户输入IP地址

connect(s,(structsockaddr*)&

server_addr,sizeof(structsockaddr));

//连接服务器端第一个参数是客户端套接字描述符,第二个参数是sockaddr指针,第三个参数是sockaddr的长度

process(s);

//客户端接收到数据处理

close(s);

//客户端关闭连接

voidprocess(ints){

ssize_tsize=0;

charbuffer[1024];

size=read(0,buffer,1024);

//从标准输入流读取数据

if(size>

write(s,buffer,size);

//发送给客户端

size=read(s,buffer,1024);

//从客户端读取数据

write(1,buffer,size);

//将数据写到标准输出

测试:

[root@localhost~]#./Server

portis62361

hello

[root@localhost~]#./Client127.0.0.1

6bytes

总结:

本文主要介绍了TCP网络数据发送与接收的流程,相关函数的使用,最后给出了一个具体的服务器与客户端通信的例子.

 

Linux网络编程之TCP(下)-I/O数据复用

1.介绍

网络数据的发送与接收有多种方式,可以直接直接从套接字读取数据或向套接字写入函数,如read/write.也可以通过向量发送与接收数据,如readv/writev.另外还可以通过消息发送与接收数据,如sendmsg/recvmsg.主要的I/O模型有以下几种:

(1)阻塞I/O-通常情况下,当数据没有到来的时候,会阻塞进程一直等待数据,如recv函数,它是最常用的模型.

(2)非阻塞I/O-当没有数据到达时,程序不会阻塞,而是立即返回,并返回一个错误.

(3)I/O复用-阻塞I/O会一直阻塞程序,而I/O复用是等待一定的时间,如果等待的时间到,那么进程就会返回.如select函数会按照一定的时间轮循环.

(4)信号驱动I/O模型-进程首先注册一个信号处理回调函数,然后继续执行,当有数据到来时,通过发送信号告诉进程,然后处理数据,

(5)异步I/O模型-与信号驱动I/O不同的,异步I/O在内核完成数据复制之后才送信号通知进程。

对于网络数据的处理,通常情况下采用阻塞I/O模型和I/O复用模型.

2.相关函数

(1)字节序的转换

字节序分为大端字节序与小端字节序,所谓小端字节序就是低字节部分存放于低地址,高字节部分存放于高地址.大端字节序正好相反.在网络数据传输中,涉及到两个字节序,一个是主机字节序,另一个是网络字节序。

主机字节序可以是小端字节序也可以是大端字节序,而网络字节序是大端字节序。

这样,在发送数据的时候,会进行字节序的相应转换。

arpa/inet.h>

uin32_thtonl(uint32_thostlong);

//主机字节序转换成网络字节序长整形

uin16_thtons(uint16_thostshort);

//主机字节序转换成网络字节序短整形

uint32_tntohl(uint32_tnetlong);

//网络字节序转换成主机字节序长整形

uint16_tntohs(uint16_tnetshort);

//网络字节序转换成主机字节序短整形

(2)IP地址的转换

netinet/inet.h>

in_addr_tinet_addr(constchar*cp);

//将字符串的IP地址转换为in_addr类型

char*inet_ntoa(structin_addrin);

//将in_addr类型的二进制地址转换成字符串

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

//将字符串类型的IP地址转换成in_addr

af-协议族

src-表示需要转换的字符串

dst-指向structin_addr指针

返回0表示转换成功,-1表示协议af不支持。

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

//把in_addr类型的二进制地址转换成字符串

参数

src-指针structin_addr的指针

dst-保存转换字符串的缓冲区

cnt-此缓冲区的长度

当发生错误时,返回NULL.成功返回指向dst的指针。

(3)获得主机信息

netdb.h>

structhostent*gethostbyname(constchar*name);

成功返回指向hostent的指针,返回NULL表示发生错误。

错误类型保存在errno中:

HOST_NOT_FOUND:

表示查询的主机不存在

NO_ADDRESS和NO_DATA:

请求的名称合法但没有合适的IP地址

NO_RECOVERY:

域名服务器不响应

TRY_AGAIN:

域名服务器出现临时性错误,请重试。

structhostent{

char*h_name;

//主机的正式名称

char**h_aliases;

//别名列表

inth_addrtype;

//主机地址类型

inth_length;

//地址长度

char**h_addr_list;

//地址列表

#defineh_addrh_addr_list[0]

structhostent*gethostbyaddr(constvoid*addr,intlen,inttype);

//通过地址来查看主机的信息

addr-structin_addr指针,表示主机的IP地址

len-所指地址的长度,即sizeof(structin_addr)

type-表示协议族

成功返回hostent指针,错误返回NULL,同上.

(4)协议名称处理函数

structprotent*getprotobyname(constchar*name);

//通过协议名获得相关的协议项

structprotent*getprotobynumber(intproto);

//通过协议值获得相关协议项

voidsetprotoent(intstayopen);

//设置协议文件的打开状态,打开/etc/protocols文件

structprotoent{

char*p_name;

//协议的官方名称

char**p_aliases;

//协议的别名

intp_proto;

//协议的值

(5)recv与send函数

ssize_trecv(ints,void*buf,size_tlen,intflags);

函数recv表示从套接字s接收数据放到数据缓冲区buf中,

buf-接收缓冲区指针

len-接收缓冲区的长度(缓冲区的size,如1024)

flags-表示接收数据的方式,通常为0

flags:

MSG_DONTWAIT-非阻塞操作,立刻返回

MSG_ERRQUEUE-错误消息从套接字错误队列接收

MSG_OOB-接收带外数据

MSG_PEEK-查看数据,不进行数据缓冲区的清空

MSG_TRUNC-返回所有数据,即使指定缓冲区过小

MSG_WAITALL-等待所有消息

成功返回接收的字节数,错误返回-1.查看errno可获得错误信息.

ssize_tsend(ints,constvoid*buf,size_tlen,intflags);

将缓冲区buf中大小为len的数据发送出去.

s-发送数据的套接字描述符

buf-发送缓冲区指针

len-要发送的数据长度(即使缓冲区大小为1024,只有10个字节数据要发送,那么len=10)

flags-发送数据的方式

成功返回发送数据的字节数,发送错误返回为-1.

(6)readv与writev函数

这两函数可以使用向量缓冲区进行数据的发送与接收,即多个缓冲区.

sys/uio.h>

ssize_treadv(intfd,conststructiovec*vector,intcount);

structivoec{

void*iov_base;

//向量缓冲区的地址

size_tiov_len;

//向量缓冲区的大小

fd-套接字描述符

vector-缓冲区指针

count-vector的个数

structiovec就是一个缓冲区,可以接收count个缓冲区的数据

成功返回表示接收到的字节数,失败返回-1,返回值保存在errno

ssize_twritev(intfd,conststructiovec*vector,count);

vector-向量缓冲区指针

count-缓冲区的个数

成功返回表示发送的字节数,失败返回-1

(6)recvmsg函数与sendmsg函数

ssize_trecvmsg(ints,structmsghdr*msg,intflags);

从套接字s中接收数据放入缓冲区msg中。

msg-structmsghdr结构体指针

flags-接收标志信息同send,recv标志.

structmsghdr{

void*msg_name;

//可选地址

socklen_tmsg_namelen;

//可选地址的长度

structiovec*msg_iov;

//接收数据的缓冲区

size_tmsg_iovlen;

//msg_iov的数量

void*msg_control;

//控制缓冲区,根据msg_flags放入不同的值

socklen_tmsg_controllen;

//控制缓冲区的长度

intmsg_flags;

//接收消息的标志

成功返回接收的字节数,失败返回-1.

ssize_tsendmsg(ints,conststructmsghdr*msg,intflags);

向msg中写入数据并发送.

flags-发送数据的标志

成功返回发送的字节数,失败返回-1.

(7)I/O复用函数

sys/select.h>

sys/time.h>

intselect(intnfds,fd_set*readfds,fd_set*writefds,fd_set*exceptfds,structtimeval*timeout);

select函数对文件描述符进行查询,查看目标是否可以进行读,写或者是错误操作,直到条件满足时才进行真正的I/O操作.

nfds-所有文件描述符最大值加1

readfds-读文件描述符集合,这个文件描述符集合监视任何可读文件,当select返回时,readfds将清除不可读的文件描述符,只留下可

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 简洁抽象

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1