1.通信流程
发送端: 接收端:
socket socket
bind
listen
connect accept
send recv
close close
2.函数接口
(1) listen
int listen(int sockfd, int backlog)
功能:
监听三次握手连接
参数:
sockfd: 套接字文件描述符
backlog: 尚未处理的连接请求最大等待个数
返回值:
成功返回0
失败返回-1
注意:
1.listen不会阻塞
(2) accept
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:
处理等待队列中的第一个请求
参数:
sockfd: 套接字文件描述符
addr: 存放请求方地址信息空间首地址
addrlen: 请求方地址信息长度
返回值:
成功返回新的文件描述符
失败返回-1
(3) recv
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:
接收数据
参数:
sockfd: 套接字文件描述符
buf: 存放接收到的数据空间首地址
len: 最大接收字节数
flags: 属性 默认为0
返回值:
成功返回实际接收到的字节数
失败返回-1
如果对方退出,recv返回0
(4) send
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:
发送数据
参数:
sockfd: 套接字文件描述符
buf: 发送数据空间首地址
len: 发送字节数
flags: 属性默认为0
返回值:
成功返回实际发送字节数
失败返回-1
(5) connect
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:
发送链接请求
参数:
sockfd: 套接字文件描述符
addr: 对方的IP地址信息
addrlen: IP地址的大小
返回值:
成功返回0
失败返回-1
代码示例:
头文件(head.h):
#ifndef _HEAD_H
#define _HEAD_H
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<netinet/ip.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<strings.h>
#endif
服务器(server.c): 文章来源:https://www.toymoban.com/news/detail-793001.html
#include"head.h"
int main(void)
{
int sockfd = 0;
int listfd = 0;
int fd = 0;
int nret = 0;
ssize_t nsize = 0;
char filename[128] = {0};
char serverfile[1024] = {0};
struct sockaddr_in server; //服务器
struct sockaddr_in client; //客户端
socklen_t len = sizeof(client);
/* 创建套接字 */
listfd = socket(AF_INET, SOCK_STREAM, 0); //监听套接字
if (-1 == listfd)
{
perror("fail to socket");
exit(1); //相当于return -1
}
/* 绑定服务器IP+Port*/
server.sin_family = AF_INET;
server.sin_port = htons(50000);
server.sin_addr.s_addr = INADDR_ANY; //随机访问本机可用IP
nret = bind(listfd, (struct sockaddr *)&server, sizeof(server));
if (-1 == nret)
{
perror("fail to bind");
exit(1);
}
/* 开始监听 */
nret = listen(listfd, 10);
if (-1 == nret)
{
perror("fail to listen");
exit(1);
}
/* 通信套接字 */
sockfd = accept(listfd, (struct sockaddr *)&client, &len);
if (-1 == sockfd)
{
perror("fail to accept");
exit(1);
}
/* 接收文件名 */
nsize = recv(sockfd, filename, sizeof(filename), 0);
if (-1 == nret)
{
perror("fail to recv");
exit(1);
}
/* 打开文件 */
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (-1 == fd)
{
perror("fail to open");
exit(1);
}
/* 接收文件数据 */
while (1)
{
bzero(serverfile, sizeof(serverfile)); //相当于memset(serverfile, 0, sizeof(serverfile));
nsize = recv(sockfd, serverfile, sizeof(serverfile), 0);
if (nsize <= 0)
{
break;
}
write(fd, serverfile, nsize);
bzero(serverfile, sizeof(serverfile));
strcpy(serverfile, "go on");
nsize = send(sockfd, serverfile, strlen(serverfile), 0);
if (-1 == nsize)
{
perror("fail to send");
exit(1);
}
}
/* 关闭文件描述符 */
close(fd);
close(listfd);
close(sockfd);
return 0;
}
客户端(client.c): 文章来源地址https://www.toymoban.com/news/detail-793001.html
#include"head.h"
int main(void)
{
int fd = 0;
int sockfd = 0;
int nret = 0;
ssize_t nsize = 0;
char filename[128] = {0};
char clientfile[1024] = {0};
struct sockaddr_in server;
/* 创建套接字 */
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == sockfd)
{
perror("fail to socket");
exit(1);
}
/* 服务器IP+Port */
server.sin_family = AF_INET;
server.sin_port = htons(50000);
server.sin_addr.s_addr = inet_addr("192.168.0.194");
/* 发送链接请求 */
nret = connect(sockfd, (struct sockaddr *)&server, sizeof(server));
if (-1 == nret)
{
perror("fail to connect");
exit(1);
}
/* 发送文件名 */
printf("请输入待发送文件:\n");
gets(filename);
nsize = send(sockfd, filename, sizeof(filename), 0);
if (-1 == nsize)
{
perror("fail to send");
exit(1);
}
/* 打开文件 */
fd = open(filename, O_RDONLY);
if (-1 == fd)
{
perror("fail to open");
exit(1);
}
/* 发送文件数据 */
while (1)
{
bzero(clientfile, sizeof(clientfile));
nsize = read(fd, clientfile, sizeof(clientfile));
if (nsize <= 0)
{
break;
}
nsize = send(sockfd, clientfile, nsize, 0);
if (-1 == nsize)
{
perror("fail to send");
exit(1);
}
bzero(clientfile, sizeof(clientfile));
nsize = recv(sockfd, clientfile, sizeof(clientfile), 0);
if (-1 == nsize)
{
perror("fail to recv");
exit(1);
}
}
/* 关闭文件描述符 */
close(fd);
close(sockfd);
return 0;
}
到了这里,关于编写程序实现利用TCP实现文件的发送的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!