源码:
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define PORT_SERV 8888
#define BUFFSIZE 1024
char receiveBuff[BUFFSIZE]={0};
#include <map>
#include <list>
#include <string>
std::list<int> clentFDs;
std::map<int,std::string> clientFD_buff_map;
#include<iostream>
using namespace std;
int main()
{
int server_sockfd, client_sockfd;
int server_len, client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
int result;
//--读取集合,测试集合
fd_set readfds, testfds;
//--建立服务器端socket
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(PORT_SERV);
server_len = sizeof(server_address);
bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
listen(server_sockfd, 5);
//--
FD_ZERO(&readfds);
//--将服务器端socket加入到读取集合中
FD_SET(server_sockfd, &readfds);
printf("server runing \n");
fflush(stdout);
while(1)
{
int fd;
int nread;
testfds = readfds;
/*阻塞,测试文件描述符变动 */
result = select(FD_SETSIZE, &testfds, (fd_set *)0,(fd_set *)0, (struct timeval *) 0);
if(result < 1)
{
perror("server error : select() result < 1");
fflush(stdout);
exit(1);
}
/*扫描所有的文件描述符*/
for(fd = 0; fd < FD_SETSIZE; fd++)
{
/*找到相关文件描述符*/
if(FD_ISSET(fd,&testfds))
{
/*判断是否为服务器套接字,是则表示为客户请求连*/
if(fd == server_sockfd)
{
client_len = sizeof(client_address);
client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address, (socklen_t *)&client_len);
//将客户端socket加入到集合中
FD_SET(client_sockfd, &readfds);
printf("adding client on fd %d\n", client_sockfd);
fflush(stdout);
clentFDs.push_back(client_sockfd);
}
/*客户端socket中有数据请求时*/
else
{
//取得数据量交给nread
ioctl(fd, FIONREAD, &nread);
/*客户数据请求完毕,关闭套接字,从集合中清除相应描述符 */
if(nread == 0)
{
close(fd);
FD_CLR(fd, &readfds);
printf("removing client on fd %d\n", fd);
fflush(stdout);
clentFDs.remove(fd);
}
/*处理客户数据请求*/
else
{
read(fd, &receiveBuff, nread);
sleep(2);
printf("client fd %d, receiveBuff :\n", fd);
printf("%s\n", receiveBuff);
fflush(stdout);
clientFD_buff_map.insert(std::pair<int,std::string>(fd,(std::string)receiveBuff));
memset(receiveBuff,0,BUFFSIZE);
/* 清空文件 */
ftruncate(fd,0);
/* 重新设置文件偏移量 */
lseek(fd,0,SEEK_SET);
}
//--服务器转发
std::map<int,std::string>::iterator it;
std::list<int>::iterator listIt;
for (listIt=clentFDs.begin();listIt!=clentFDs.end();listIt++) {
for (it = clientFD_buff_map.begin();it!=clientFD_buff_map.end();it++) {
if(it->first != *listIt){
std::cout<< "client "<<it->first << " => " << it->second << '\n';
write(*listIt, it->second.c_str(), it->second.length());
}
}
}
clientFD_buff_map.clear();
}
}
}//for
}//while
}
买了一台百度云服务器,ubuntu16.04lts ,公网ip
然后搭建了FTP 服务器,
把源码放到服务器上面编译
运行服务端以上程序
然后 自己写的 QtAndroid tcp客户端
运行在 家里面的pc机上面的tcp客户端通信 ,就像qq功能,只是一个示范