linux socket通信程序,linux socket通信

listen函数一般在调用bind之后-调用accept之前调用。

fd_set

select()机制中提供一fd_set的数据结构,实际上是一long类型的数组,每一个数组元素都能与一打开的文件句柄(不管是socket句柄,还是其他文件或命名管道或设备句柄)建立联系,建立联系的工作由程序员完成,当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执行了select()的进程哪一socket或文件发生了可读或可写事件。

FD_ZERO(&set);                 /*将set清零使集合中不含任何fd*/

FD_SET(fd, &set);               /*将fd加入set集合*/

FD_CLR(fd, &set);               /*将fd从set集合中清除*/

FD_ISSET(fd, &set);            /*在调用select()函数后,用FD_ISSET来检测fd在fdset集合中的状态是否变化返回整型,当检测到fd状态发生变化时返回真,否则,返回假(0)*/

select

select()的机制中提供一fd_set的数据结构,实际上是一long类型的数组, 每一个数组元素都能与一打开的文件句柄(不管是Socket句柄,还是其他 文件或命名管道或设备句柄)建立联系,建立联系的工作由程序员完成, 当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执 行了select()的进程哪一Socket或文件可读。

accept函数

处于监听状态的服务器在获得客户机的连接请求后,会将其放置在等待队列中。当系统空闲时,将接受客户机的连接请求。接收客户机的连接请求使用accept函数,该函数的具体信息如表13.6所示。

表13.6   accept函数头文件

函数形式int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

返回值成功失败是否设置errno

返回新的套接字文件描述符1是

说明:

accept函数用于面向连接类型的套接字类型(SOCK_STREAM和SOCK_SEQPACKET)。accept函数将从连接请求队列中获得连接信息,创建新的套接字,并返回该套接字的文件描述符。新创建的套接字用于服务器与客户机的通信,而原来的套接字仍然处于监听状态。

accept函数的sockfd参数为监听的套接字描述符。addr参数为指向结构体sockaddr的指针。参数addrlen为addr参数指向的内存空间的长度。

服务器程序

#include

#include

#include

#include

#include

#include

#include

#include

int main()

{

int server_socket,client_socket;

int server_len,clinet_len;

struct sockaddr_in server_address;

struct sockaddr_in client_address;

int iResult;

fd_set readfds,testfds;

//建立服务器端SOCKET

server_socket = socket(AF_INET,SOCK_STREAM,0);

server_address.sin_family = AF_INET;

server_address.sin_addr.s_addr = htonl(INADDR_ANY);

server_address.sin_port = htons(9734);

server_len = sizeof(server_address);

//将服务器端的SOCKET与端口和IP绑定

bind(server_socket,(struct sockaddr *)&server_address,server_len);

//在服务器端监听客户请求

listen(server_socket,5);

FD_ZERO(&readfds);

FD_SET(server_socket,&readfds);

while(1)

{

char ch;

int fd;

int nread;

testfds = readfds;

printf("server waiting\n");

//监听到客户端消息

iResult = select(FD_SETSIZE,&testfds,(fd_set *)0,(fd_set *)0,(struct timeval *) 0);

if(iResult < 1)

{

printf("server error\n");

exit(-1);

}

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

{

if(FD_ISSET(fd,&testfds))

{

if(fd == server_socket)

{

clinet_len = sizeof(client_address);

client_socket = accept(server_socket,(struct sockaddr *)&client_address,( socklen_t *)&clinet_len);

FD_SET(client_socket,&readfds);

printf("addding client on fd %d\n",client_socket);

}

else

{

ioctl(fd,FIONREAD,&nread);

if(nread == 0)

{

close(fd);

FD_CLR(fd,&readfds);

printf("remoing client on fd %d\n",fd);

}

else

{

read(fd,&ch,1);

sleep(5);

printf("sering client on fd %d\n",fd);

ch++;

write(fd,&ch,1);

}

}

}

}

}

return 0;

}

客户端程序#include

#include

#include

#include

#include

#include

#include

int main()

{

int sockfd;

int len;

struct sockaddr_in address;

int result;

char ch = 'A';

sockfd = socket(AF_INET,SOCK_STREAM,0);

address.sin_family = AF_INET;

address.sin_addr.s_addr = inet_addr("127.0.0.1");

address.sin_port = htons(9734);

len = sizeof(address);

//将客户端的SOCKET与服务器端口进行链接

result = connect(sockfd,(struct sockaddr *)&address,len);

if(result == -1)

{

printf("connect error\n");

exit(-1);

}

write(sockfd,&ch,1);

read(sockfd,&ch, 1);

printf("char from server = %c \n",ch);

close(sockfd);

exit(0);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值