sockaddr,accept函数作用

伏羲号

sockaddr,accept函数作用?

accept()

sockaddr,accept函数作用

原型: int accept (int sockfd, struct sockaddr *addr, socklen_t *addrlen)

功能描述:accept()函数仅被TCP类型的服务器程序调用。

从已完成连接队列返回下一个建立成功的连接,如果已完成连接队列为空,线程进入阻塞态睡眠状态。成功时返回套接字描述符,错误时返回-1。

如果accpet()执行成功,返回由内核自动生成的一个全新socket描述符,用它引用与客户端的TCP连接。

通常我们把accept()第一个参数成为监听套接字(listening socket),把accept()功能返回值成为已连接套接字(connected socket)。

一个服务器通常只有1个监听套接字,监听客户端的连接请求;服务器内核为每一个客户端的TCP连接维护1个已连接套接字,用它实现数据双向通信。

参数解释:

sockfd -- socket()函数返回的描述符;

addr -- 输出一个的sockaddr_in变量地址,该变量用来存放发起连接请求的客户端的协议地址;

addrten -- 作为输入时指明缓冲器的长度,作为输出时指明addr的实际长度。

ho在c语言中是什么意思?

这是输出格式符

%hu代表以 unsigned short格式输出整数

%hx 代表以16进制的 输出short类型的整数

比如

printf("%hu",-30); 会输出 65506

printf("%hx",-30); 会输出FFE2

// 结构体

struct sockaddr_in sockaddr4;printf函数格式字符:

常用的有以下几种格式字符:

(1)d格式字符。用来输出十进制整数。有以下几种用法:

1、%d,按整型数据的实际长度输出。

2、%md,m为指定的输出字段的宽度。

3、%ld,输出长整型数据。

(2)o格式符,以八进制整型式输出

如何对终端命令录像?

system是一个使用简单,设计复杂的程序。它主要包含fork exec waitpid三个步骤。下来我来还原楼主的错误:程序A:/* socksrv.c*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h> /* for struct sockaddr_in*/#define BACKLOG 10#define MYPORT 4000int main(){ char *addr; int sockfd; int new_fd; struct sockaddr_in my_addr, their_addr; int res; int sin_size; char *buf; /* 取得套接字描述符*/ sockfd = socket(AF_INET, /* domain*/ SOCK_STREAM, /* type*/ 0); /* protocol*/ if (sockfd == -1) { perror("socket"); exit(1); } /* Init sockaddr_in */ my_addr.sin_family = AF_INET; /* 注意: 应使用主机字节顺序*/ my_addr.sin_port = htons(MYPORT); /* 注意: 应使用网络字节顺序*/ my_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* 使用自己的 IP 地址 */ bzero(&(my_addr.sin_zero), 8); /* 结构的其余的部分须置 0*/ /* 指定一个套接字使用的地址及端口*/ res = bind(sockfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)); if (res == -1) { perror("bind"); exit(1); } /* 监听请求, 等待连接*/ res = listen(sockfd, BACKLOG); /* 未经处理的连接请求队列可容纳的最大数目*/ if (res == -1) { perror("listen"); exit(1); }system("./hello&"); /* 接受对方的连接请求, 建立连接,返回一个新的连接描述符. * 而第一个套接字描述符仍在你的机器上原来的端口 listen() */ sin_size = sizeof(struct sockaddr_in); new_fd = accept(sockfd, (void *)&their_addr, &sin_size); buf = (char *)malloc(255); if (buf == NULL) { printf("malloc failed\n"); exit(1); } /* 接受对方发来的数据*/ res = recv(new_fd, buf, 255, 0); if (res == -1) { perror("recv()"); exit(1); } /* 关闭本次连接*/ close(new_fd); /* 关闭系统监听*/ close(sockfd); printf("recv data:%s\n", buf); free(buf); return 0;}程序B:hello,在主程序中用system("./hello&)调用。#include <stdlib.h>int main(){ while(1){ sleep(1000); }return 0;}编译后运行程序A。我们可以在其它终端窗口看到 ./A ./hello正在运行,netstat -a 看到,tcp 4000端口被 占用。我们用Ctrl+c中断程序A模拟楼主的崩溃操作。这时,再在其它终端窗口看看,./A没有了。./hello还在运行。netstat -a看到。4000端口还在占用。这时再次运行./A,提示bind: Address already in use而退出。情况就是这样。因为执行system时,系统会fork一个A的子进程,再去执行B.当你的A崩溃以后,它的一个子进程实际上还在运行,它打开的端口,文件,等还在使用。所以再次运行A时,由于自定的互斥机制而退出。如:再次绑定端口时提示端口已在使用。杀死B后,A的子进程结束,它的资源释放,所以才能再次运行A。我建议楼主使用exec系列函数来启动B。

发表评论

快捷回复: 表情:
AddoilApplauseBadlaughBombCoffeeFabulousFacepalmFecesFrownHeyhaInsidiousKeepFightingNoProbPigHeadShockedSinistersmileSlapSocialSweatTolaughWatermelonWittyWowYeahYellowdog
评论列表 (暂无评论,101人围观)

还没有评论,来说两句吧...