一 客户端数据反射交互
(1)实验内容
要求:利用数据报套接字实现数据传输
- 客户端创建UDP套接字,向指定的服务端发送数据;
- 服务端接收到新数据,显示是谁发送过来的,并把该数据回传给发送方;
- 服务端使用多线程来实现并发
(2)实现方法
Client
unsigned int port;
char recvData[255];
cin >> sendData;
sendto(sclient,sendData, 255, 0, (sockaddr *)&sin, len);
int ret = recvfrom(sclient, (char *)&port, 4, 0, (sockaddr *)&sin, &len);
sin.sin_port=htons(port);
ret = recvfrom(sclient, recvData,255, 0, (sockaddr *)&sin, &len);
if(ret > 0) cout<<recvData<<endl;
while(1)
{
cout<<"Input your message:";
cin >> sendData;
sendto(sclient,sendData, sizeof(sendData), 0, (sockaddr *)&sin, len);
int ret = recvfrom(sclient, recvData,255, 0, (sockaddr *)&sin, &len);
if(ret > 0) cout<<"From server:"<<recvData<<endl;
cin>>s;
if (s!=s1)
break;
}
server
while (true)
{
char recvData[255];
char sendData[255];
int ret = recvfrom(serSocket, recvData, 255, 0, (sockaddr *)&remoteAddr, &nAddrLen);
NUM++;
if (ret > 0) cout<<"Connect a new user ,total Nummber is "<<NUM<<endl;
mystruct.client = remoteAddr;
mystruct.userid = NUM;
memcpy(mystruct.recvData,recvData,255);
hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)&mystruct, 0, NULL);
}
子线程代码
DWORD WINAPI ClientThread(LPVOID lpParameter)
{
SOCKET ChildSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
······
}
int PORT=1024;
while ( PORT <= 65535){
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons( PORT);
serAddr.sin_addr.S_un.S_addr = INADDR_ANY;
if (bind(ChildSocket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
PORT++;
else
break;
}
my_struct mystruct = (my_struct) lpParameter;
client = mystruct ->client;
userid = mystruct->userid;
nAddrLen = mystruct->nAddrLen;
sendto(ChildSocket,(const char *)&PORT,4, 0, (sockaddr *)&client, nAddrLen);
sendto(ChildSocket, mystruct->recvData, 255, 0, (sockaddr *)&client, nAddrLen);
while(1)
{
int ret = recvfrom(ChildSocket,mystruct-> recvData, 255, 0, (sockaddr *)& client,& nAddrLen);
if (ret > 0) cout<<"FROM user"<<userid<<":"<<mystruct->recvData<<endl;
sendto(ChildSocket, mystruct->recvData, 255, 0, (sockaddr *)& client, nAddrLen);
}
(3)实验实现
服务器端
多个客户端同时连接 ,实现用户识别及交叉发送数据
用户1
用户2
二 使用UDP套接字实现文件传输
(1)实验内容
- 客户端向服务端发送文件名
- 客户端向服务端传输文件内容
- 双方关闭套接字
(2)实验方法
Client
unsigned int port=0;
char recvData[255];
cout<<"Input your filename:";
cin >> name;
sendto(sclient,name, 20, 0, (sockaddr *)&sin, len);
int ret = recvfrom(sclient, (char *)&port, 4, 0, (sockaddr *)&sin, &len);
sin.sin_port=htons(port);
fp = fopen(name,"rb");
if(fp==NULL) {cout<<"no suchfile again input:"; }
fseek(fp,0L,SEEK_END);
file_size = ftell( fp );
fseek(fp,0L,SEEK_SET);
sendto(sclient,(const char *)&file_size, 4, 0, (sockaddr *)&sin, len);
while(file_size)
{
if(file_size>=1024){
fread(data,1,1024,fp);
sendto(sclient, data, 1024, 0, (sockaddr *)&sin, len);
file_size -= 1024;
}
else {
fread(data,1,file_size,fp);
sendto(sclient, data, file_size, 0, (sockaddr *)&sin, len);
file_size = 0;
}
}
// 读取文件并传送
Server
int NUM=0;
typedef struct MyStruct
{
sockaddr_in client;
int nAddrLen;
char recvData[255];
int userid;
char name[20];
}MyStruct, *my_struct ;
while (true)
{
char recvData[255];
char sendData[255];
memset(recvData,0,255);
recvfrom(serSocket,recvData, 20, 0, (sockaddr *)& remoteAddr,& nAddrLen);
NUM++;
cout<<"Connect a new user ,total Nummber is "<<NUM<<endl;
mystruct.userid = NUM;
mystruct.client = remoteAddr;
memcpy(mystruct.name,recvData,20);
hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)&mystruct, 0, NULL);
}
创建新线程
SOCKET ChildSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
while ( PORT <= 65535){
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons( PORT);
serAddr.sin_addr.S_un.S_addr = INADDR_ANY;
if (bind(ChildSocket, (sockaddr *)&serAddr, sizeof(serAddr)) == SOCKET_ERROR)
PORT++;
else
break;
}
my_struct mystruct = (my_struct) lpParameter;
client = mystruct ->client;
userid = mystruct->userid;
nAddrLen = mystruct->nAddrLen;
sendto(ChildSocket,(const char *)&PORT,4, 0, (sockaddr *)&client, nAddrLen);
char a[4];
unsigned int len=0;
recvfrom(ChildSocket,(char *)&len, 4, 0, (sockaddr *)& client,& nAddrLen);
FILE *dest_fp;
dest_fp = fopen(mystruct->name, "ab");
while(1)
{
while(len)
{
if(len>=1024) {recvfrom(ChildSocket,data, 1024, 0, (sockaddr *)& client,& nAddrLen) ;fwrite(data,1, 1024, dest_fp);fflush(dest_fp);len = len - 1024;}
else {recvfrom(ChildSocket,data, len, 0, (sockaddr *)& client,& nAddrLen) ;fwrite(data,1,len,dest_fp);fflush(dest_fp);len = 0;}
}
fclose(dest_fp);
}
(3)实验实现
服务器每次用户连接创建新的线程
用户一
用户二
文件夹
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)