socket编程(二)
来源:互联网 发布:ug nx8.0数控编程教程 编辑:程序博客网 时间:2024/06/05 19:03
TCP客户/服务器模型
一个典型的TCP客户/服务器模型流程如下:
回射客户/服务器
1. 客户端从标准输入获取一行数据,然后发送到服务器;
2. 服务器收到信息后,不处理消息内容,直接将消息内容原封不动地发送给客户端;
3. 客户端收到后,在标准输出上打印出来。
socket、bind、listen、accept、connect
socket函数
- 包含头文件
<sys/socket.h>
- 功能:创建一个套接字用于通信
- 原型
int socket(int domain, int type, int protocol);
- 参数
- domain: 指定通信协议族(protocol family)
- type: 指定socket类型,流式套接字SOCK_STREAM, 数据报套接字SOCK_DGRAM,原始套接字SOCK_RAW
- protocol:协议类型
- 返回值:成功返回非负整数,它与文件描述符类似,我们把它们称为套接口描述字,简称套接字。失败返回-1
bind函数
- 包含头文件
<sys/socket.h>
- 功能:绑定一个本地地址到套接字
- 原型:
int bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen);
- 参数
- sockfd:socket函数返回的套接字
- addr:要绑定的地址
- addrlen:地址长度
- 返回值:成功放回0,失败返回-1
listen函数
- 包含头文件
<sys/socket.h>
- 功能:将套接字用于监听进入的连接
- 原型:
int listen(int sockfd, int backlog);
- 参数:
- sockfd:socket函数返回的套接字
- backlog:规定内核为此排队的最大连接个数
- 返回值:成功返回0,失败返回-1
- 一般来说,listen应该socketbind函数之后,函数accept之前调用
- 对于给定的监听套接口,要维护两个队列
- 1、已由并到达服务器,服务器正在等待完成相应的TCP三次握手过程
- 2、已完成连接的队列
- 两队列之和不超过backlog
一旦调用listen函数后,该套接字便成了被动套接字,否则默认为主动套接字。
accept函数
- 包含头文件
<sys/socket.h>
- 功能:从已完成连接的队列返回第一个,如果已完成连接队列为空,则阻塞
- 原型
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
- 参数:
- sockfd:服务器套接字
- addr:将返回对等方的套接字地址(也就是将对方的地址存储于addr指向的结构体中)
- addrlen:返回对等方套接字地址长度(也就是将对方的地址长度存储于addrlen指向的区域中,addrlen所指的区域一定要有初始值,否则accept会失败)
- 返回值:成功返回非负整数(一个已连接套接字(这个套接字不是被动套接字,而是一个主动套接字)),失败返回-1
connect函数
- 包含头文件
<sys/socket.h>
- 功能:建立一个addr所指定的套接字
- 原型
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
- 参数
- sockfd:未连接套接字
- addr:要连接的套接字地址
- addrlen:第二个参数addr长度
- 返回值:成功返回0,失败返回-1
TCP回射客户/服务器程序
服务器端
/************************************************************************* > File Name: echoserv.c > Author: Marvin > Mail: czwwonder4@outlook.com > Created Time: Thu Jun 29 14:27:59 2017 ************************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#include <sys/types.h>#include <unistd.h>#include <errno.h>int main(){ int listenfd; //创建一个套接字 if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ perror("Create socket failed."); exit(1); } /*int socket(int domain, int type, int protocol);*/ struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(9000); 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){ perror("bind error."); exit(1); } //监听 if(listen(listenfd, SOMAXCONN) < 0){ perror("listen() error."); exit(1); } struct sockaddr_in peeraddr; socklen_t peerlen = sizeof(peeraddr); int conn;// char recvbuf[1024]; //接收客户端连接,客户地址信息存放在peeraddr中 if((conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen)) < 0){ perror("accept() error."); exit(1); } 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;}
客户端
/************************************************************************* > File Name: echoclient.c > Author: Marvin > Mail: czwwonder4@outlook.com > Created Time: Thu Jun 29 14:27:59 2017 ************************************************************************/#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/socket.h>#include <arpa/inet.h>#include <netinet/in.h>#include <sys/types.h>#include <unistd.h>#include <errno.h>int main(){ int sock; //创建一个套接字 if((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0){ perror("Creat socket failed."); exit(1); } /*int socket(int domain, int type, int protocol);*/ struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(9000); servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); /*servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");*/ /*inet_aton("127.0.0.1", &servaddr.sin_addr);*/ if(connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){ perror("connect() error"); exit(1); } char sendbuf[1024] = {0}; char recvbuf[1024] = {0}; while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL){ write(sock, sendbuf, strlen(sendbuf)); read(sock, recvbuf, sizeof(recvbuf)); memset(&sendbuf, 0, sizeof(sendbuf)); fputs(recvbuf, stdout); memset(&recvbuf, 0, sizeof(recvbuf)); } close(sock); return 0;}
演示结果
阅读全文
0 0
- socket编程(二)
- socket编程(二)
- Socket 编程(二)
- socket编程(二)
- socket编程(二)
- socket编程(二)
- Java Socket编程(二)Socket基础
- Java Socket编程(二)
- Java Socket编程(二)
- Java Socket编程(二)
- socket编程原理(二)
- java Socket编程(二)
- Java Socket编程(二)
- Java socket 编程(二)
- linux socket 编程(二)
- Socket 基础编程(二)
- socket编程入门(二)
- Java Socket编程(二)-3
- Spring Cloud Feign Client 实现MultipartFile上传文件功能
- PAT甲级 1014
- YII2框架学习 扩展篇(一) 模块化设计
- 并发队列比较
- Android PopupWindow初步使用
- socket编程(二)
- jQuery -- touch事件之滑动判断(左右上下方向)
- 写作建议
- Android (BroadcastReceiver基础)
- python 线程、协程简单使用
- Service使用技巧
- HDU 4798 Skycity【计算机几何】【阅读题】
- MQTT,RabbitMQ初步使用
- 【Sicily】1002. 等价二叉树