linux & windows tcp客户端和服务端,发送和接收文件(公网测试通过)
程序员文章站
2022-03-04 08:49:38
...
tcp服务端:
如果客户端发送download命令,则给该客户端发送文件
#ifdef WIN32
#include <winsock2.h>
#include <WS2tcpip.h>
#include <Windows.h>
#elif 1
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#define _PORT_ 9999
#define SERVER_IP "127.0.0.1"
#define _BACKLOG_ 10
int is_begin_with(const char * str1,char *str2)
{
if(str1 == NULL || str2 == NULL)
return -1;
int len1 = strlen(str1);
int len2 = strlen(str2);
if((len1 < len2) || (len1 == 0 || len2 == 0))
return -1;
char *p = str2;
int i = 0;
while(*p != '\0')
{
if(*p != str1[i])
return 0;
p++;
i++;
}
return 1;
}
int main()
{
#ifdef WIN32
WORD sockVersion = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(sockVersion, &wsaData) != 0)
{
return 0;
}
#elif 1
#define INVALID_SOCKET ~0
#endif
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET)
{
printf("socket error !");
return 0;
}
struct sockaddr_in server_socket;
struct sockaddr_in client_socket;
memset(&server_socket, 0, sizeof(server_socket));
server_socket.sin_family = AF_INET;
server_socket.sin_port = htons(_PORT_);
server_socket.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sock, (struct sockaddr *)&server_socket, sizeof(struct sockaddr_in)) < 0)
{
printf("bind error,error code is %d,error string is :%s\n",errno,strerror(errno));
close(sock);
return 1;
}
if(listen(sock,_BACKLOG_) < 0)
{
printf("listen error,error code is %d,error string is %s\n",errno,strerror(errno));
close(sock);
return 2;
}
printf("bind and listen success,wait accept...\n");
for(;;)
{
socklen_t len = sizeof(struct sockaddr);
int client_sock = accept(sock, (struct sockaddr *)&client_socket, &len);
if(client_sock == INVALID_SOCKET)
{
printf("accept error, error is %d,errstring is %s\n",errno,strerror(errno));
close(sock);
return 3;
}
char buf_ip[INET_ADDRSTRLEN];
memset(buf_ip,'\0',sizeof(buf_ip));
inet_ntop(AF_INET,&client_socket.sin_addr,buf_ip,sizeof(buf_ip));
printf("get connect,ip is %s,port is %d\n",buf_ip,ntohs(client_socket.sin_port));
char buf[1024];
memset(buf,'\0',sizeof(buf));//跟前面的初始化对比
read(client_sock, buf, sizeof(buf));
//printf("client :# %s\n",buf);
if(is_begin_with(buf, "download") != 1) {
//printf("command unvalid!");
continue;
}
FILE *fp;
fp = fopen("./maroon.rcc" , "r");
//fseek( fp , 0 , SEEK_SET);
char buffer[4096];
int totalbytes = 0;
while(!feof(fp)){
len = fread(buffer, 1, sizeof(buffer), fp);
int bflen = write(client_sock, buffer, len);
totalbytes += len;
printf("write in bytes:%d, total written bytes:%d\n", bflen, totalbytes);
}
printf("write done, total bytes:%d\n", totalbytes);
}
close(sock);
return 0;
}
tcp客户端:
以二进制的方式接收文件
//是否从服务器上下载资源文件
#define download_rcc_from_remote_server 1
void DownloadService::downloadfromserver() {
#if download_rcc_from_remote_server
#ifdef WIN32
WORD sockVersion = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(sockVersion, &wsaData) != 0)
{
return;
}
#elif 1
#define INVALID_SOCKET ~0
#endif
struct sockaddr_in server_sock;
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
memset(&server_sock, 0, sizeof(server_sock));
server_sock.sin_family = AF_INET;
#ifdef WIN32
inet_pton(AF_INET, SERVER_IP, &server_sock.sin_addr);
#elif
inet_pton(AF_INET, SERVER_IP, &server_sock.sin_addr);
#endif
server_sock.sin_port = htons(SERVER_PORT);
int ret = ::connect(sock, (struct sockaddr*)&server_sock, sizeof(server_sock));
if(ret < 0)
{
printf("connect failed...,errno is %d,errstring is %s\n",errno,strerror(errno));
}
qDebug("connect is success...\n");
#ifdef WIN32
send(sock, "download", 9, 0);
#elif 1
write(sock, buf, strlen(buf) + 1);
#endif
FILE *pf;
pf = fopen("./maroon.rcc", "w+");
fclose(pf);
pf = fopen("./maroon.rcc", "wb");
int tl = 0;
int timeout = 1500;
//设置接收超时时间
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(int));
int i = 0;
while(true) {
char recvBuf[4096] = { 0 };
#ifdef WIN32
int len = recv(sock, recvBuf, 4096, 0);
#elif 1
read(sock,buf,sizeof(buf));
#endif
if(len <= 0)
break;
tl += len;
qDebug() << "recv rcc part:" << len << ", total bytes:" << tl;
fwrite(recvBuf, len, 1, pf);
}
qDebug() << "recv done";
fclose(pf);
#ifdef WIN32
WSACleanup();
#elif
close(sock);
#endif
#endif
emit plugindownfinished(true);
}