TCP通信
TCP发端:
socket (流式套接字创建) - > connect (发送连接请求) ->
send (发送数据)-> recv(接受数据) -> close
TCP收端:
socket(流式套接字创建) ()-> bind(绑定自己的端口和ip)
listen (监听客户端发送的连接请求) -> accept (处理等待连接队列中的第一个连接请求) 返回值是一个新的文件描述符 -> send (发送数据) -> recv -> close
1.connect
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:
发送链接请求
参数:
sockfd:套接字文件描述符
addr:目的地址存放空间首地址
addrlen:IP地址的大小
返回值:
成功返回0
失败返回-1
2.send
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:
发送数据
参数:
sockfd:文件描述符
buf:发送数据空间首地址
len:发送数据的长度
flags:属性默认为0
返回值:
成功返回实际发送字节数
失败返回-1
3.recv
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:
接收数据
参数:
sockfd:套接字文件描述符
buf:存放数据空间首地址
len:最大接收数据的长度
flags:属性默认为0
返回值:
成功返回实际接收字节数
失败返回-1
如果对方退出,返回0
4.listen
int listen(int sockfd, int backlog);
功能:
监听客户端发送的连接请求
该函数不会阻塞
参数:
sockfd:套接字文件描述符
backlog:允许等待的尚未被处理的三次握手请求的最大个数
返回值:
成功返回0
失败返回-1
5.accept
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:
处理等待连接队列中的第一个连接请求
该函数具有阻塞功能(如果没有人发送链接请求,会阻塞等待)
参数:
socket:套接字文件描述符
address:存放IP地址的空间首地址
addrlen:存放IP地址大小空间首地址
返回值:
成功返回一个新的文件描述符
失败返回-1
eg:发端
#include"head.h"
int main(void)
{
int ret = 0;
int sockfd = 0;
struct sockaddr_in seraddr; // 服务端的ip
char tmpbuff[1024] = {0};
ssize_t nsize = 0;
sockfd = socket(AF_INET,SOCK_STREAM,0); //流式套接字文件
if(sockfd == -1)
{
perror("faile to soket");
return -1;
}
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(50000);
seraddr.sin_addr.s_addr = inet_addr("192.168.1.107");
ret = connect(sockfd,(struct sockaddr *)&seraddr, sizeof(seraddr)); //建立链接的三次握手
if(ret == -1)
{
perror("fail to connect");
return -1;
}
gets(tmpbuff);
nsize = send(sockfd,tmpbuff,strlen(tmpbuff),0); //发送
if(nsize == -1);
{
perror("fail to send");
return -1;
}
memset(tmpbuff,0,sizeof(tmpbuff));
nsize = recv(sockfd, tmpbuff, sizeof(tmpbuff), 0); //接收
if (-1 == nsize)
{
perror("fail to recv");
return -1;
}
printf("服务端向你发送了:%s\n",tmpbuff);
close(sockfd);
return 0;
}
eg:收端
#include "head.h"
int main(void)
{
int ret = 0;
int sockfd = 0;
int confd = 0; //定义流套接字
char tmpbuff[1024] = {0};
ssize_t nsize = 0;
struct sockaddr_in seraddr; //服务端的ip
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(50000);
seraddr.sin_addr.s_addr = INADDR_ANY; //绑定自己的端口ip
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == sockfd)
{
perror("fail to socket");
return -1;
}
ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (-1 == ret)
{
perror("fail to bind");
return -1;
}
ret = listen(sockfd, 10); //监听客户端发送的连接请求
if (-1 == ret)
{
perror("fail to listen");
return -1;
}
confd = accept(sockfd, NULL, NULL); //处理等待连接队列中的第一个连接请求) 返回值是一个新的文件描述符
if (-1 == confd)
{
perror("fail to accept");
return -1;
}
nsize = recv(confd, tmpbuff, sizeof(tmpbuff), 0); //拿着新的文件描述去发接收数据
if (-1 == nsize)
{
perror("fail to recv");
return -1;
}
printf("RECV:%s\n", tmpbuff);
memset(tmpbuff, 0, sizeof(tmpbuff));
gets(tmpbuff);
nsize = send(confd, tmpbuff, strlen(tmpbuff), 0); //新的文件描述符发送数据
if (-1 == nsize)
{
perror("fail to send");
return -1;
}
close(confd);
close(sockfd);
return 0;
}