socket编程(二)---- 简单的服务器端
2016-03-21 20:43
288 查看
socket编程(二)---- 简单的服务器端
1. socket通信流程
![](http://img.blog.csdn.net/20160321171731701)
2. socket服务器端函数描述
socket()
创建一个socket套接字,
domail:协议域,又称协议族,一般为 AF_INET (IPv4 Internet protocols)
type:指定套接字类型, 一般为SOCK_STREAM(流式套接字)
protocol:指定协议,一般传参0
如果创建套接字成功,返回一个套接字的文件描述符,如果失败,返回-1
详见手册 man socket
bind()
将本地地址与一套接字绑定
sockfd:创建的套接字的文件描述符
addr:套接字地址结构
addrlen:套接字地址大小
如果绑定地址成功返回0,失败返回-1
详见手册 man bind
listen()
监听,将创建的套接字转变为被动套接字
sockfd:已绑定的套接字的文件描述符
backlog:等待连接队列的最大长度
如果监听成功则返回0,否则返回-1
详见手册 man accept
accept()
从连接队列中获取一个连接,注意,当客户端向服务器发送一个连接请求时,该客户端会直接和服务器在后台进行三次握手,此时对accept函数是不可见的,当握手完成,该链接会被保存到一个队列之中,而accept函数则是从该队列中获取一个连接,顾在accept之前,就已经建立了连接。
sockfd:已绑定的套接字的文件描述符
address:如果accept到了连接,那么将客户端的地址等信息写到该结构体中。
address_len:address结构体的空间大小
如果accept到了一个链接,那么返回一个关于这个链接的文件描述符,accept失败则返回-1,如果没有链接到来,该函数会阻塞
详见手册 man 3 accept
3. 搭建一个简单的socket服务器
参考文献:http://blog.csdn.net/yueguanghaidao/article/details/7035248?ticket=ST-74446-QWLN73sAGSZp7dFOBpul-passport.csdn.net
1. socket通信流程
2. socket服务器端函数描述
socket()
#include <sys/types.h> #include <sys/socket.h> int socket(int domain, int type, int protocol);
创建一个socket套接字,
domail:协议域,又称协议族,一般为 AF_INET (IPv4 Internet protocols)
type:指定套接字类型, 一般为SOCK_STREAM(流式套接字)
protocol:指定协议,一般传参0
如果创建套接字成功,返回一个套接字的文件描述符,如果失败,返回-1
详见手册 man socket
bind()
#include <sys/types.h> #include <sys/socket.h> int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
将本地地址与一套接字绑定
sockfd:创建的套接字的文件描述符
addr:套接字地址结构
addrlen:套接字地址大小
如果绑定地址成功返回0,失败返回-1
详见手册 man bind
listen()
#include <sys/types.h> #include <sys/socket.h> int listen(int sockfd, int backlog);
监听,将创建的套接字转变为被动套接字
sockfd:已绑定的套接字的文件描述符
backlog:等待连接队列的最大长度
如果监听成功则返回0,否则返回-1
详见手册 man accept
accept()
#include <sys/socket.h> int accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len);
从连接队列中获取一个连接,注意,当客户端向服务器发送一个连接请求时,该客户端会直接和服务器在后台进行三次握手,此时对accept函数是不可见的,当握手完成,该链接会被保存到一个队列之中,而accept函数则是从该队列中获取一个连接,顾在accept之前,就已经建立了连接。
sockfd:已绑定的套接字的文件描述符
address:如果accept到了连接,那么将客户端的地址等信息写到该结构体中。
address_len:address结构体的空间大小
如果accept到了一个链接,那么返回一个关于这个链接的文件描述符,accept失败则返回-1,如果没有链接到来,该函数会阻塞
详见手册 man 3 accept
3. 搭建一个简单的socket服务器
#include <stdio.h> #include <errno.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main() { int sockfd = 0; int connfd = 0; int ret = -1; sockfd = socket(AF_INET, SOCK_STREAM, 0); /* 创建socket */ if( -1 == sockfd ) { perror("func socket() error!"); return 0; } struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(4444); /* 设置监听的端口 */ addr.sin_addr.s_addr = inet_addr("127.0.0.1"); /* 绑定的地址 */ if(-1 == bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) ) /* 绑定地址 */ { perror("func bind() error!"); return 0; } if(-1 == listen(sockfd, 10)) /* 监听 */ { perror("func listen() error!"); return 0; } struct sockaddr_in client_addr; /* 用于保存客户端的地址信息 */ memset(&client_addr, 0, sizeof(client_addr)); socklen_t client_len = sizeof(client_addr); connfd = accept(sockfd, (struct sockaddr *)&client_addr, &client_len); /* 获取一个链接 */ if(-1 == connfd) { perror("func accept() error~"); exit(0); } printf("client %s connected.\n", inet_ntoa(client_addr.sin_addr)); char buff[100]; /* 用于接收和发送数据 */ memset(buff, 0, sizeof(buff)); ret = recv(connfd, buff, sizeof(buff), 0); /* 接收数据,返回接收的数据长度,等于0表示对方已关闭 */ if(ret < 0) { perror("func recv() error!"); close(connfd); close(sockfd); return 0; } else if(0 == ret) { printf("peer has closed.\n"); close(connfd); close(sockfd); return 0; } else printf("recv: %s\n", buff); ret = write(connfd, buff, strlen(buff)); /* 发送数据,Linux上一切设备皆文件,顾所有的操作都能以文件的形式完成,成功返回发送的长度 */ if(ret < 0) { perror("func write() error!"); } close(connfd); close(sockfd); return 0; }
参考文献:http://blog.csdn.net/yueguanghaidao/article/details/7035248?ticket=ST-74446-QWLN73sAGSZp7dFOBpul-passport.csdn.net
相关文章推荐
- 智能指针的理解
- thinkphp学习记事
- java基本知识点
- Java之HashMap在多线程情况下导致死循环的问题
- Java 进阶 之 检查型异常与非检查型异常
- C/C++—— 除了用类成员函数访问类私有成员变量外,还可以通过类对象地址来直接访问和修改类的私有成员变量
- java语言程序设计第十版(Introduce to java 10th) 课后习题 chapter6-28
- Java核心知识点-Java编译原理
- [leetcode]题解+经验总结 自己做法+评论区mostvotes汇总 (只包含部分easy难度)
- Spider 之 爬虫 基本工作原理
- 【转载】Eclipse the user operation is waiting for "buiding workspace" to complete
- java第十三节-集合框架概况
- Java集合源码学习笔记(五)ArrayList,LinkedList,Vector和Hashtable,HashMap的比较
- C++中泛型使用导致的膨胀问题
- C# 版本 支付
- Spring框架中的定时器 如何使用和配置
- 网易在线编程题
- PHP学习(三)----面向对象
- java 编程思想 第五章 初始化与清理
- spring lazy-init和 prototype