tcp服务器通信流程
监听套接字 和 已连接套接字区别
监听套接字只负责监听是否有新的连接到来
已连接套接字负责和客户端通信
listen:
#include <sys/socket.h>
int listen(int sockfd, int backlog);
函数功能: 将套接字由主动变被动,并且创建两个连接队列
参数:
sockfd: 套接字
backlog: 已完成连接队列和未完成连接队列上连接数之和的最大值 一般写128
返回值 成功返回0 失败返回-1
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能: 从已连接队列提取新的连接,并且会创建一个新的已连接套接字
参数:
sockfd: 套接字 监听套接字
addr: 保持客户端地址信息结构体
addrlen: 结构体大小的地址
返回值::
成功返回已连接套接字 失败返回-1
tcp服务器代码实现:
/* ************************************************************************
* Filename: 02tcp_server.c
* Description:
* Version: 1.0
* Created: 2019年09月18日 15时27分07秒
* Revision: none
* Compiler: gcc
* Author: YOUR NAME (),
* Company:
* ************************************************************************/
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
//创建套接字
int lfd = socket(AF_INET,SOCK_STREAM,0);
if(lfd < 0)
perror("");
//绑定
struct sockaddr_in myaddr;
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(9999);
myaddr.sin_addr.s_addr = 0;//本机的ip都绑定
bind(lfd,(struct sockaddr*)&myaddr,sizeof(myaddr));//绑定
//监听
listen(lfd,128);
//提取
struct sockaddr_in cliaddr;
socklen_t len = sizeof(cliaddr);
int cfd = accept(lfd,(struct sockaddr *)&cliaddr,&len);//提取
if(cfd < 0 )
perror("");
char ip[16]="";
printf("client ip=%s port=%d\n",
inet_ntop(AF_INET,&cliaddr.sin_addr.s_addr,ip,16),ntohs(cliaddr.sin_port));
//读写
while(1)
{
char buf[256]="";
//回射服务器
int ret = read(cfd,buf,sizeof(buf));
if(ret == 0)
{
printf("client close\n");
break;
}
printf("recv = [%s]\n",buf);
write(cfd,buf,ret);
}
//关闭
close(lfd);
close(cfd);
return 0;
}