socket客户/服务器模型
用到的函数
socket函数

流式套接字就是TCP,数据包套接字就是UDP
一个程序最多打开一般来说是1024个文件描述符,由一个系统的参数来确定的,叫open files。
bind函数
listen函数
accept函数
在完成连接队列为空时,accept会阻塞
- 第二个和第三个参数,要么都是空指针,要么都不是空指针
connect函数
read函数
write函数
例子
客户端编程
#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>int main(){int sock;if(sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)//其实前两个已经表示为是tcp协议了,第三个参数可以填0{ERR_EXIT("socket");//报错误的宏}struct sockaddr_in servaddr;memset(&servaddr, 0, sizeof(servaddr));//全部填充0servaddr.sin_family = AF_INET;servaddr.sin_prot = htons(5188);servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");if(connect(sock, (struct sockaddr*)servaddr, sizeof(servaddr)) < 0){ERR_EXIT("connect");}char recvbuf[1024] = {0};char sendbuf[1024] = {0};while(fgets(sendbuf, sizeof(sendbuf), stdin)!= NULL){write(sock, sendbuf, strlen(sendbuf));read(sock, recvbuf, sizeof(recvbuf));fputs(recvbuf, stdout);memset(sendbuf, 0, sizeof(sendbuf));//清空缓存区memset(recvbuf, 0, sizeof(recvbuf));}close(sock);return 0;}
服务器编程
监听套接字:listenfd
已连接套接字:conn
注意这里listen之后,客户端就已经能够搜索到了
#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <netinet/in.h>#include <arpa/inet.h>#include <string.h>int main(){int listenfd;if(listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) < 0)//其实前两个已经表示为是tcp协议了,第三个参数可以填0{ERR_EXIT("socket");//报错误的宏}struct sockaddr_in servaddr;memset(&servaddr, 0, sizeof(servaddr));//全部填充0servaddr.sin_family = AF_INET;servaddr.sin_prot = htons(5188);servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//参数表示本机的任意地址,以下两种也是正确的写法//servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");//inet_aton("127.0.0.1", &servaddr.sin_addr);if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){//一旦绑定完成,这个套接字就会被认为是被动套接字,否则是主动套接字。ERR_EXIT("bind");}if(listen(listenfd, SOMAXCONN) < 0)//后面的宏,代表队列的最大值{ERR_EXIT("listen");}struct sockaddr_in peeraddr;socklen_t peerlen = sizeof(peeraddr);int conn;if((conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen)) < 0){//这里返回值是文件描述符ERR_EXIT("accept");}char recvbuf[1024];while(1){memset(recvbuf, 0, sizeof(recvbuf));int ret = read(conn, recvbuf, sizeof(recvbuf));fputs(recvbuf, stdout);write(conn, recvbuf, ret);}close(conn);close(listenfd);return 0;}




