浅谈TCP socket
来源:互联网 发布:mid函数的使用方法vb 编辑:程序博客网 时间:2024/06/03 05:40
Socket,用来实现应用的通信,是应用非常广的一个api,今天就来揭开它的神秘面纱。
客户端
引入头文件
#include <winsock2.h>
初始化socket的DLL
WSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData
创建套接字
SOCKET socket(int domain, int type, int protocol);
domain 是协议域,包括
- AF_INET 对应 ipv4
- AF_INET6 对应 ipv6
type 是连接类型
- SOCK_STREAM,提供面向连接的稳定数据传输,即TCP协议。
- SOCK_DGRAM,提供的是数据报(datagram),使用UDP协议。
- protocol,一般设为0,内核会自动匹配。
存储服务器信息
客户端要去连接服务器,所以应该存储服务器的IP地址和端口号。
这边已经在 netinet/in.h 帮我们实现了一个结构体 struct sockaddr_in 来存储服务器信息。作为函数参数时强制转换为sockaddr。
struct sockaddr_in { short sin_family; // 必须为AF_INET,因为是IPv4; unsigned short sin_port; // 存储port No struct in_addr sin_addr; //存储IP地址 char sin_zero[8]; };
网络的字节顺序为大端法,我们要想正确通信,就必须统一格式。
那么什么是大小端呢?
大端是高位字节存在低地址中,小端是低位字节存在低地址中。
因此如果本地端口格式是小端要转为大端。
htons(PORT)就是将本机的字节序转化为网络的字节序。
连接服务器
int connect(SOCKET sockfd, const struct sockaddr *serv_addr,socklen_t addrlen)
- SOCKET sockfd,本地的socket
- const struct sockaddr *serv_addr, 将SOCKADDR_IN的对象转为 sockaddr 指针
- socklen_t address_len 就是sockaddr的大小
收发消息
ssize_t send(SOCKET sockfd, const void *buf, size_t len, int flags)ssize_t recv(SOCKET sockfd, void *buf, size_t len, int flags)
- SOCKET sockfd,本地的socket描述字
- const void *buf,字符串指针,数据缓冲区
- size_t len,接受的长度
- int flags,通常从设为0
断开
int PASCAL FAR closesocket(SOCKET s);
关闭套接字
服务器
创建服务器套接字
存储服务器信息
bind绑定
将服务器套接字与服务器信息绑定在一起
int bind(SOCKET socket, const struct sockaddr* address, socklen_t address_len);
- SOCKET socket,服务器本地的socket
- const struct sockaddr *address, 将SOCKADDR_IN的对象转为 sockaddr 指针
- socklen_t address_len 就是sockaddr的大小
监听
int listen(SOCKET sockfd, int backlog)
listen()函数可以让套接字进入被动监听状态
sockfd为需要进入监听状态的套接字,backlog 为请求队列的最大长度。
所谓被动监听,是指当没有客户端请求时,套接字就会处于睡眠状态,只有当接收到客户端请求时,套接字才会被唤醒来响应请求。
accept
用accept来接受客户端的请求,这时候会产生一个新的套接字,记重点,新的,之后的通信全部用这个新的套接字,原来的套接字还在监听客户端的请求。
int accept(SOCKET sockfd, struct sockaddr *addr, socklen_t *addrlen)
- SOCKET sockfd,服务器本地的socket
- struct sockaddr *addr,用于存储客户端的IP和端口号等
- socklen_t address_len,描述addr的大小
注意这边的accept是会阻塞的,那么什么是阻塞,就是如果没有接收到,那么我就会一直等在这边,比如我们刚学c语言的scanf函数的时候,它就会阻塞到那里等待用户输入。
包括send和recv也是会阻塞的。
新套接字用来收发信息
- 关闭套接字
参考资料:
1.简单的聊天室实现(上):通信-SOCKET
2. TCP Socket Programming 學習筆記
3. 使用listen()和accept()函数
- 浅谈TCP socket
- TCP/UDP/SOCKET/HTTP浅谈
- 浅谈TCP/UDP、IP 、Socket、HTTP
- 浅谈SOCKET-TCP编程中send函数的机制
- 浅谈TCP/IP网络编程中socket的行为
- 浅谈Windows Socket程序设计(TCP和UDP)
- 浅谈TCP/IP网络编程中socket的行为
- 浅谈TCP/IP网络编程中socket的行为
- 浅谈TCP/IP网络编程中socket的行为
- 浅谈TCP/IP网络编程中socket的行为
- 浅谈TCP/IP网络编程中socket的行为
- 浅谈TCP/IP网络编程中socket的行为
- 浅谈TCP/IP网络编程中socket的行为
- 浅谈TCP/IP网络编程中socket的行为
- 浅谈TCP/IP网络编程中socket的行为
- [转]浅谈TCP/IP网络编程中socket的行为
- 浅谈 TCP/IP 网络编程中 socket 的行为
- 浅谈TCP/IP网络编程中socket的行为
- mysql存储过程
- Codeforces Round #451 (Div. 2) B. Proper Nutrition
- Gym
- java设计模式学习—抽象工厂模式
- Guava篇-缓存
- 浅谈TCP socket
- 二叉树遍历
- deepmind_lab 运行 ASSETS 和 MAPS文件依赖的东西
- LINTCODE——Compute 24 Game
- post与get 区别 (转载学习)
- c++基础
- [MongoDB] 安装MongoDB Mac OS X & RHEL/CentOS/Fedora
- 优先级队列
- More Effective C++ 31. Making functions virtual with respect to more than one object