Здравствуйте, gandjustas, Вы писали:
G>Код покажи
Сервер и клиент работают с сокетами через один и тот же класс.
Метод инициализации сокетов одинаковый для клиента и сервера:
WSADATA wsadata;
void Initialize()
{
if(WSAStartup(MAKEWORD(2,2),&wsadata)){
throw new СIOException(WSAGetLastError());
}
mMainSocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(mMainSocket==INVALID_SOCKET){
throw new СIOException(WSAGetLastError());
}
bool opt = true;
if(::setsockopt(mMainSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt))==SOCKET_ERROR){
throw new СIOException(WSAGetLastError());
}
BOOL noDelay=TRUE;
if(::setsockopt(mMainSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&noDelay, sizeof(BOOL))==SOCKET_ERROR){
throw new СIOException(WSAGetLastError());
}
}
Дальше инициализация идет для сервера:
void Listen()
{
SOCKADDR_IN addr;
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr("192.168.1.3");
addr.sin_port=htons(33657);
if(bind(mMainSocket,(sockaddr*)&addr,sizeof(addr))==SOCKET_ERROR){
throw new СIOException(WSAGetLastError());
}
if(listen(mMainSocket, SOMAXCONN)==SOCKET_ERROR){
throw new СIOException(WSAGetLastError());
}
SOCKADDR tmpAddr;
int len = sizeof(tmpAddr);
mActiveSocket=accept(mMainSocket,(sockaddr*)&tmpAddr,(int*)&len);
if(mActiveSocket==INVALID_SOCKET){
throw new СIOException(WSAGetLastError());
}
}
И для клиента:
void Send()
{
SOCKADDR_IN addr;
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr("192.168.1.3");
addr.sin_port=htons(33657);
mActiveSocket=mMainSocket;
if(connect(mActiveSocket,(sockaddr*)&addr,sizeof(addr))==SOCKET_ERROR){
throw new СIOException(WSAGetLastError());
}
}
и два метода чтения и записи:
CData Read()
{
CData data;
if(mActiveSocket){
// получаем размер пакета
ULONG dataLen=0;
int rcvLen=recv(mActiveSocket, (char*)&dataLen, sizeof(ULONG), 0);
if(rcvLen==0){
throw new CIOException("Соединение разорвано()");
}else if(rcvLen==SOCKET_ERROR){
throw new CIOException(WSAGetLastError());
}
//выделям память под пакет
data.AllocData(dataLen)
char* dataAddr=data.GetDataAddr();
// принимаем пакет
while(dataLen>0){
rcvLen=recv(mActiveSocket, dataAddr, dataLen, 0);
if(rcvLen==0){
throw new СIOException(WSAGetLastError());
}else if(rcvLen==SOCKET_ERROR){
throw new СIOException(WSAGetLastError());
}
dataAddr+=rcvLen;
dataLen-=rcvLen;
}
}
return data;
};
void Write(CData& data)
{
if(mActiveSocket){
// передаем размер пакета
ULONG size=data.GetDataSize();
if(send(mActiveSocket,(char*)&size,sizeof(ULONG),0)==SOCKET_ERROR){
throw new СIOException(WSAGetLastError());
}
char* dataAddr=data.GetDataAddr();
ULONG dataSize=data.GetDataSize();
// передаем пакет
while(dataSize>0){
int sentLen=0;
if((sentLen=send(mActiveSocket,dataAddr,dataSize,0))==SOCKET_ERROR){
throw new СIOException(WSAGetLastError());
}
dataSize-=sentLen;
dataAddr+=sentLen;
}
}
};
ну и собственно основной код для сервера и клиента:
void ClientCore(СIOCtrl* cio)
{
try
{
cio->Initialize();
cio->Send();
SendRain(cio,100,1000);
SendRain(cio,1000,1000);
cio->Write(_stopFlag);
cio->CloseConnection();
cio->ShutDown();
}
catch (CIOException* e)
{
cio->ShutDown();
delete e;
}
}
void SendRain(СIOCtrl* cio,ULONG size,int iterations)
{
CData data;
data.AllocData(size);
DWORD ticks=::GetTickCount();
int i;
for(i=0; i < iterations; i++){
cio->Write(data);
if(vio->Read()!=size){
echo("Ошибка при передаче данных");
break;
}
}
ticks=::GetTickCount()-ticks;
printf("Передано %d блоков данных по %d байт за %d мс\r\n",i,size,ticks);
}
void ServerCore(СIOCtrl* cio)
{
try
{
cio->Initialize();
cio->Listen();
while(true){
CData data=cio->Read();
if(data ==_stopFlag){
echo("Режим завершен успешно.");
break;
}else{
CData size=data.GetDataSize();
cio->Write(size);
}
}
cio->ShutDown();
}
catch (CIOException* e)
{
cio->ShutDown();
delete e;
}
}