【嵌入式Linux学习七步曲之第七篇 Linux的高级应用编程】TCP/IP网络编程函数解析

本文深入解析了嵌入式Linux环境下的TCP/IP网络编程,重点介绍了常用的socket函数及其在网络通信中的作用,包括缓冲区管理和连接管理等关键概念。
摘要由CSDN通过智能技术生成

TCP/IP网络编程函数解析

 

Sailor_forever  sailing_9806@163.com 转载请注明

http://blog.csdn.net/sailor_8318/archive/2009/01/08/3736837.aspx

 

 

 

socket(建立一个socket通信)

相关函数

acceptbindconnectlisten

表头文件

#include<sys/types.h>
#include<sys/socket.h>

定义函数

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

函数说明

socket()用来建立一个新的socket,也就是向系统注册,通知系统建立一通信端口。参数domain 指定使用何种的地址类型,完整的定义在/usr/include/bits/socket.h 内,底下是常见的协议:
PF_UNIX/PF_LOCAL/AF_UNIX/AF_LOCAL UNIX
进程通信协议
PF_INET/AF_INET Ipv4
网络协议
PF_INET6/AF_INET6 Ipv6
网络协议
PF_IPX/AF_IPX IPX-Novell
协议

参数

type有下列几种常见数值:
SOCK_STREAM
提供双向连续且可信赖的数据流,即TCP。支持OOB 机制,在所有数据传送前必须使用connect()来建立连线状态。
SOCK_DGRAM
使用不连续不可信赖的数据包连接
SOCK_RAW
提供原始网络协议存取
protocol
用来指定socket所使用的传输协议编号,通常此参考不用管它,设为0即可。

返回值

成功则返回socket处理代码,失败返回-1错误原因存于errno中。

错误代码

EPROTONOSUPPORT 参数domain指定的类型不支持参数typeprotocol指定的协议
ENFILE
核心内存不足,无法建立新的socket结构
EMFILE
进程文件表溢出,无法再建立新的socket
EACCESS
权限不足,无法建立typeprotocol指定的协议
ENOBUFS/ENOMEM
内存不足
EINVAL
参数domain/type/protocol不合法

范例

参考connect()

 

 

bind(对socket定位)

相关函数

socketacceptconnectlisten

表头文件

#include<sys/types.h>
#include<sys/socket.h>

定义函数

int bind(int sockfd,struct sockaddr * my_addr,int addrlen);

函数说明

bind()用来设置给参数sockfdsocket一个名称。此名称由参数my_addr指向一sockaddr结构,对于不同的socket domain定义了一个通用的数据结构
struct sockaddr
{
unsigned short int sa_family;
char sa_data[14];
};
sa_family
为调用socket()时的domain参数,即AF_xxxx值。
sa_data
最多使用14个字符长度。
sockaddr结构会因使用不同的socket domain而有不同结构定义,例如使用AF_INET domain,其socketaddr结构定义便为
struct socketaddr_in
{
unsigned short int sin_family;
uint16_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
struct in_addr
{
uint32_t s_addr;
};
sin_family
即为sa_family
sin_port
为使用的port编号
sin_addr.s_addr
IP 地址
sin_zero
未使用。

参数

addrlensockaddr的结构长度。

返回值

成功则返回0,失败返回-1,错误原因存于errno中。

错误代码

EBADF 参数sockfd 非合法socket处理代码。
EACCESS
权限不足
ENOTSOCK
参数sockfd为一文件描述词,非socket

范例

参考listen()

 

 

listen(等待连接)

相关函数

socketbindacceptconnect

表头文件

#include<sys/socket.h>

定义函数

int listen(int s,int backlog);

函数说明

listen()用来等待参数s socket连线。参数backlog指定同时能处理的最大连接要求,如果连接数目达此上限则client端将收到ECONNREFUSED的错误。Listen()并未开始接收连线,只是设置socketlisten模式,真正接收client端连线的是accept()Listen为非阻塞调用。通常listen()会在socket()bind()之后调用,接着才调用accept()。套接口s处于一种变动模式,申请进入的连接请求被确认,并排队等待被接受。这个函数特别适用于同时有多个连接请求的服务器;如果当一个连接请求到来时,队列已满,那么客户将收到一个ECONNREFUSED错误。

返回值

成功则返回0,失败返回-1,错误原因存于errno

附加说明

listen()只适用SOCK_STREAMSOCK_SEQPACKETsocket类型。如果socketAF_INET则参数backlog 最大值可设至128

错误代码

EBADF 参数sockfd非合法socket处理代码
EACCESS
权限不足
EOPNOTSUPP
指定的socket并未支援listen模式。

范例

#include<sys/types.h>

#include<sys/socket.h>

#include<netinet/in.h>

#include<arpa/inet.h>

#include<unistd.h>

#define PORT 1234

#define MAXSOCKFD 10

main()

{

        int sockfd,newsockfd,is_connected[MAXSOCKFD],fd;

        struct sockaddr_in addr;

        int addr_len = sizeof(struct sockaddr_in);

        fd_set readfds;

        char buffer[256];

        char msg[ ] ="Welcome to server!";

 

        if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0){

                perror("socket");

                exit(1);

        }

 

        bzero(&addr,sizeof(addr));

        addr.sin_family =AF_INET;

        addr.sin_port = htons(PORT);

        addr.sin_addr.s_addr = htonl(INADDR_ANY);

        if(bind(sockfd, (struct sockaddr *)&addr,sizeof(addr))<0){

                perror("connect");

                exit(1);

        }

 

        if(listen(sockfd,3)<0){

                perror("listen");

                exit(1);

        }

 

        for(fd=0;fd<MAXSOCKFD;fd++)

        is_connected[fd]=0;

        while(1){

                FD_ZERO(&readfds);

                FD_SET(sockfd,&readfds);

               

                for(fd=0;fd<MAXSOCKFD;fd++)

                if(is_connected[fd]) FD_SET(fd,&readfds);

                if(!select(MAXSOCKFD,&readfds,NULL,NULL,NULL))continue;

               

                for(fd=0;fd<MAXSOCKFD;fd++)

                if(FD_ISSET(fd,&readfds)){

                       if(sockfd = =fd){

                               if((newsockfd = accept (sockfd, (struct sockaddr *)&addr,&addr_len))<0)

                               perror("accept");

                               write(newsockfd,msg,sizeof(msg));

                               is_connected[newsockfd] =1;

                               printf("cnnect from %s/n",inet_ntoa(addr.sin_addr));

                       }else{

                               bzero(buffer,sizeof(buffer));

                               if(read(fd,buffer,sizeof(buffer))<=0){

                               printf("connect closed./n");

                               is_connected[fd]=0;

                               close(fd);

                               }else

                               printf("%s",buffer);

                       }

                }

        }

}

执行

$ ./listen
connect from 127.0.0.1
hi I am client
connected closed.

 

 

connect(建立socket连线)

相关函数

socketbindlisten

表头文件

#include<sys/types.h>
#inc

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值