服务器部分
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int sendFile(int sockfd, const char *filename)
{
// 打开文件
FILE *fp = fopen(filename, "r");
if(fp < 0) {
printf("open file failed!\n");
return -1;
}
// 获取并发送文件大小信息
fseek(fp, 0, SEEK_END);
long fsize = ftell(fp);
fseek(fp, 0, SEEK_SET);
if(send(sockfd, &fsize, sizeof(long), 0) != sizeof(long)) {
printf("error: send file size failed!\n");
fclose(fp);
return -1;
}
// 发送文件主体
char buf[512];
long n, count = 0;
while((n=fread(buf, 1, 512, fp)) > 0)
send(sockfd, buf, n, 0);
fclose(fp);
return 0;
}
char *recvString(int sockfd)
{
long len = 0;
if(recv(sockfd, &len, sizeof(long), 0) != sizeof(long)) {
printf("send string size failed!\n");
return NULL;
}
char *string = (char *)malloc(len+1);
if(string == NULL) {
printf("malloc string failed!\n");
return NULL;
}
if(recv(sockfd, string, len, 0) != len) {
printf("recv string failed!\n");
return NULL;
}
string[len] = '\0';
return string;
}
int main()
{
int sockfd;
struct sockaddr_in serAddr, cliAddr;
// 创建套接字描述符
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("socket creation failed...\n");
return 1;
}
// 设置服务器地址和端口
serAddr.sin_family = AF_INET;
serAddr.sin_addr.s_addr = inet_addr("127.10.25.5");
serAddr.sin_port = htons(8085);
// 将服务器地址和端口与 sockfd 绑定
if(bind(sockfd, (struct sockaddr*)&serAddr, sizeof(serAddr)) != 0) {
printf("socket bind failed...\n");
return 1;
}
// 设置监听
if(listen(sockfd, 5) != 0) {
printf("listen failed...\n");
return 1;
}
// 挂起捕获
int connfd, len = sizeof(cliAddr);
if((connfd = accept(sockfd, (struct sockaddr*)&cliAddr, &len)) > 0) {
printf("connected %s port %d\n", inet_ntoa(cliAddr.sin_addr), ntohs(cliAddr.sin_port));
}
// 发送文件
sendFile(connfd, "music.mp3");
char *recvMsg = recvString(connfd);
printf("%s\n", recvMsg != NULL ? recvMsg : "error");
close(connfd);
return 0;
}
客户端部分
#include <sys/socket.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int recvFile(int sockfd, const char *filename)
{
// 新建文件
FILE *fp = fopen(filename, "w");
if(fp == NULL) {
printf("open file failed!\n");
return -1;
}
// 先获取文件大小
long fsize = 0;
if(recv(sockfd, &fsize, sizeof(long), 0) != sizeof(long)) {
printf("error: recv file size failed!\n");
fclose(fp);
return -1;
}
// 获取文件
char buf[1024];
long n, count = 0;
while(count < fsize && (n = recv(sockfd, buf, 1024, 0))>0) {
fwrite(buf, 1, n, fp);
count += n;
}
fclose(fp);
return 0;
}
int sendString(int sockfd, const char *string)
{
if(string == NULL)
return -1;
long len = strlen(string);
if(send(sockfd, &len, sizeof(long), 0) != sizeof(long)) {
printf("send string size failed!\n");
return -1;
}
if(send(sockfd, string, len, 0) != len) {
printf("send string failed!\n");
return -1;
}
return 0;
}
int main()
{
int sockfd;
struct sockaddr_in serverAddr;
// 创建套接字描述符
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
printf("socket creation failed...\n");
return 1;
}
// 设置要连接的服务器地址和端口
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.10.25.5");
serverAddr.sin_port = htons(8085);
// 进行连接
if (connect(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) != 0) {
printf("connection with the server failed...\n");
return 1;
}
// 接收文件
recvFile(sockfd, "mymusic.mp3");
// 发送消息
sendString(sockfd, "I recvived!");
close(sockfd);
return 0;
}
有时候端口绑定失败,可以强制绑定
int opt = 1;
// 强制将套接字连接到 8080 端口
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
网友评论