sockaddr,accept函数作用?
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。
还没有评论,来说两句吧...