TCP服务器
TCP协议概念
TDP协议是在整个网络分层的传输层的协议,具有以下特性
1.传输层协议
2.有连接
3.可靠传输
4.面向字节流
TCP服务器常见的API
创建 socket 文件描述符(客户端+服务端)
int socket(int domain, int type, int protocol);
damain:IPV4通信,AF_INET
type:类型:面向数据流,选择SOCK_STREAM
protocol:选择0即可
返回值:成功返回一个文件描述符,失败返回-1
绑定端口号 ( 服务器)
int bind(int socket, const struct sockaddr *address,socklen_t address_len);
socket:socket得到的文件描述符
address:struct sockaddr *的一个结构体,一般需要从struct sockaddr_in 结构体强转而来,使用前需初始化
address_len:address结构体的大小
返回值:成功返回0,失败返回-1
开始监听socket (服务器)
int listen(int socket, int backlog);
socket:socket得到的文件描述符
backlog:全连接数 = backlog+1,全连接:即已经建立好,但还没有被accept调用的连接
返回值:成功返回0,失败返回-1
接收请求 ( 服务器)
int accept(int socket, struct sockaddr* address,
socklen_t* address_len);
socket:socket得到的文件描述符
address:结构体
address_len:结构体的大小
返回值:成功返回一个新的文件描述符,这个文件描述符是用于真正通信的,失败返回-1
建立连接 (客户端)
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
socket:socket得到的文件描述符
address:结构体,使用之前需初始化
address_len:结构体的大小
返回值:成功返回0,失败返回-1
写入数据(客户端/服务端)
ssize_t write(int fd, const void *buf, size_t count);
fd:文件描述符
buf:写的数据
count:希望写的大小
返回值:实际上写的大小
读取数据(客户端/服务端)
ssize_t read(int fd, void *buf, size_t count);
fd:文件描述符
buf:读的数据
count:希望读的大小
返回值:实际上读的大小
服务端的建立过程
1.socket获取文件描述符
2.bind通过ip,port进行绑定
3.listen将服务器设为监听状态
4.accept,提取出所监听套接字的等待连接队列中第一个连接请求,创建一个新的套接字,并返回指向该套接字的文件描述符,使用该文件描述符进行通信
5.等待客户端输入,再读取数据
客户端的建立过程
1.socket获取文件描述符
2.connect,连接上服务器
3.写入数据
实现TCP服务器
客户端输入数据,服务端读取数据,并将消息回显到客户端上
server.h
#pragma once
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
using namespace std;
class Server
{
public:
Server(string _ip,short _port):ip(_ip),port(_port),socketfd(-1)
{
}
~Server()
{
if(socketfd>=0)
{
close(socketfd);
}
}
public:
void InitServer()
{
socketfd = socket(AF_INET,SOCK_STREAM,0);
if(socketfd<0)
{
cerr<<"socket error"<<endl;
exit(2);
}
struct sockaddr_in ser;
ser.sin_family = AF_INET;
ser.sin_port = htons(port);
ser.sin_addr.s_addr = inet_addr(ip.c_str());
int bd = bind(socketfd,(sockaddr*)&ser,sizeof(ser));
if(bd<0)
{
cerr<<"bind error"<<endl;
exit(3);
}
int lis = listen(socketfd,5);
if(lis<0)
{
cerr<<"listen error"<<endl;
exit(4);
}
}
void Run()
{
struct sockaddr_in peer;
socklen_t len = sizeof(peer);
while(1)
{
int newfd = accept(socketfd,(sockaddr*)&peer,&len);
if(newfd<0)
{
cerr<<"accept error"<<endl;
continue;
}
ServerIO(newfd);
}
}
void ServerIO(int fd)
{
while(1)
{
char buf[1024] = {
0};
ssize_t s = read(fd,buf,sizeof(buf));
if(s>0)
{
cout<<"来自client的消息:"<<buf<<endl;
write(fd,buf,sizeof(buf)