//服务端 服务端转发消息 多线程阻塞模式
#include< stdio.h >
#include< stdlib.h >#include< windows.h >
#include< winsock.h >
#include <vector>
#include <afx.h>
#include <algorithm>
using namespace std;
#pragma comment( lib, "ws2_32.lib" )
#define PORT 2048
#define BACKLOG 10
#define TRUE 1
vector<int> all_user;
struct ip_st
{
char cli_ip[50];
SOCKET cli_so;
};
CString s_user;
CString temp;
char tt[20];
DWORD _stdcall recv_f(LPVOID lp)
{
ip_st* so = new ip_st;
memcpy(so,lp,sizeof(ip_st));
CString analyse_data;
CString trans_to;
USES_CONVERSION;
while(1)
{
char buf[100];
memset(buf,0,100);
int bb = recv(so->cli_so,buf,100,0);
if( bb != -1)
{
if (bb == 0)
{
printf( "%s 离线!\n",so->cli_ip);
closesocket(so->cli_so);
delete so;
return 0;
}else
{
//分析数据
analyse_data = buf;
int an_lab = analyse_data.Find(L":");
int rr = -1;
if (an_lab != -1)
{
analyse_data = analyse_data.Left(an_lab);
if (s_user.Find(analyse_data) != -1)
{
int a = _wtoi(analyse_data);
analyse_data = buf;
analyse_data = analyse_data.Mid(an_lab+1,analyse_data.GetLength()-an_lab);
printf("%d对%d说:%s\n",so->cli_so,a,T2A(analyse_data));
if (send(a,T2A(analyse_data),strlen(T2A(analyse_data)),0) != -1)
{
rr = send(so->cli_so,"服务器收到数据并转发成功!\n",sizeof("服务器收到数据并转发成功!\n"),0);
if (rr != -1)
{
printf("反馈客户端成功!\n");
}
}
}
}
发送用户列表
s_user = L"";
for (vector<int>::iterator it= all_user.begin();it != all_user.end();it++)
{
if (*it == so->cli_so)
{
temp.Format(L"自己在线,",*it);
}else
{
temp.Format(L"%d:用户在线,",*it);
}
s_user += temp;
}
rr = send(so->cli_so,T2A(s_user),strlen(T2A(s_user)),0);
if (rr == -1)
{
printf("用户列表发送失败!");
}
}
}else
{
printf( "%s 意外掉线!\n",so->cli_ip);
vector<int>::iterator findit = find(all_user.begin(),all_user.end(),so->cli_so);
all_user.erase(findit);
for (vector<int>::iterator it = all_user.begin();it != all_user.end();it++)
{
memset(tt,0,20);
sprintf(tt,"%d掉线",so->cli_so);
send(*it,tt,strlen(tt),0);
}
s_user = L"";
for (vector<int>::iterator it= all_user.begin();it != all_user.end();it++)
{
if (*it == so->cli_so)
{
temp.Format(L"自己在线,",*it);
}else
{
temp.Format(L"%d:用户在线,",*it);
}
s_user += temp;
}
for (vector<int>::iterator it = all_user.begin();it != all_user.end();it++)
{
send(*it,T2A(s_user),strlen(T2A(s_user)),0);
}
closesocket(so->cli_so);
delete so;
return 0;
}
}
return 0;
}
int sin_size;
int iServerSock;
DWORD __stdcall acc(LPVOID lp)
{
int iClientSock;
struct sockaddr_in ClientAddr;
while( TRUE )
{
sin_size = sizeof( struct sockaddr_in );
iClientSock = accept( iServerSock, ( struct sockaddr * )&ClientAddr, &sin_size );
USES_CONVERSION;
if( iClientSock == -1 )
{
printf( "accept调用失败!\n" );
WSACleanup( );
exit( 0 );
}else
{
all_user.push_back(iClientSock);
s_user = L"";
for (vector<int>::iterator it= all_user.begin();it != all_user.end();it++)
{
temp.Format(L"%d:用户在线,",*it);
s_user += temp;
}
for (vector<int>::iterator it = all_user.begin();it != all_user.end();it++)
{
send(*it,T2A(s_user),strlen(T2A(s_user)),0);
}
}
printf( "服务器连接到%s\n", inet_ntoa(ClientAddr.sin_addr));
ip_st temp;
temp.cli_so = iClientSock;
sprintf(temp.cli_ip,"%s",inet_ntoa( ClientAddr.sin_addr ));
CreateThread(0,0,recv_f,(LPVOID)&temp,0,0);
}
return 0;
}
void main( void )
{
char *buf = "hello, world!\n";
struct sockaddr_in ServerAddr;
WSADATA WSAData;
if( WSAStartup( MAKEWORD( 1, 1 ), &WSAData ) )//初始化
{
printf( "initializationing error!\n" );
WSACleanup( );
exit( 0 );
}
if( ( iServerSock = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )
{
printf( "创建套接字失败!\n" );
WSACleanup( );
exit( 0 );
}
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons( PORT );//监视的端口号
ServerAddr.sin_addr.s_addr = inet_addr("127.0.0.1");//本地IP
memset( & ( ServerAddr.sin_zero ), 0, sizeof( ServerAddr.sin_zero ) );
if( bind( iServerSock, ( struct sockaddr * )&ServerAddr, sizeof( struct sockaddr ) ) == -1 )
{
printf( "bind调用失败!\n" );
WSACleanup( );
exit( 0 );
}
if( listen( iServerSock, BACKLOG ) == -1 )
{
printf( "listen调用失败!\n" );
WSACleanup( );
exit( 0 );
}
CreateThread(0,0,acc,0,0,0);
system("pause");
}
//客户端
#include< stdio.h >
#include< stdlib.h >
#include< windows.h >
#include< winsock.h >
#include<string>
#include <afx.h>
using namespace std;
#pragma comment( lib, "ws2_32.lib" )
#define PORT 2048
#define BACKLOG 10
#define TRUE 1
#define MAXDATASIZE 100
SOCKET iClientSock;
std::string ss_list;
DWORD __stdcall recv_msg(LPVOID lp)
{
char buf[100];
while(1)
{
memset(buf,0,100);
int return_val = recv(iClientSock,buf,100,0);
if (return_val != -1)
{
if (strlen(buf) >0)
{
printf("%s\n",buf);
}
}else
{
printf("服务器断开连接!\n");
return 0;
}
}
return 0;
}
void main( void )
{
char buf[ MAXDATASIZE ];
struct sockaddr_in ServerAddr;
int numbytes;
WSADATA WSAData;
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ){return;}
if ( LOBYTE( wsaData.wVersion ) != 2 ||HIBYTE( wsaData.wVersion ) != 2 )
{
WSACleanup( );
return;
}
if( ( iClientSock = socket(AF_INET, SOCK_STREAM,0)) == INVALID_SOCKET )
{
printf( "创建套接字失败!\n" );
WSACleanup( );
exit( 0 );
}
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons( PORT );
// ServerAddr.sin_addr = *( ( struct in_addr * )he->h_addr );
ServerAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );//记得换IP
memset( &( ServerAddr.sin_zero ), 0, sizeof( ServerAddr.sin_zero ) );
if( connect(iClientSock,( struct sockaddr * ) & ServerAddr, sizeof( struct sockaddr ) ) == -1 )
{
printf( "connect失败!" );
WSACleanup( );
exit( 0 );
}
//HANDLE had1 = CreateThread(0,0,send_msg,(LPVOID)&iClientSock,0,0);
HANDLE had = CreateThread(0,0,recv_msg,0,0,0);
while(TRUE)
{
char buf[100];
memset(buf,0,100);
scanf("%s",&buf);
int lab = send(iClientSock,buf,strlen(buf),0);
if (lab == strlen(buf))
{
printf("发送 %d 个字节成功!\n",lab);
}
}
system("pause");
}