通过udp实现一个聊天室。
只需要1个服务器 ,可以支持n个client。
服务器的工作就是接收到消息并转发给其他客户端。客户端需要同时开启接收了发送线程,时时刻刻接收服务器发来的信息以及将自己的信息发送到服务器上。
server:
#include
#include
#include
#include
#pragma comment(lib,"ws2_32.lib")
#define DEFAULT_PORT 5051//FOR RECV
#define DEFAULT_PORTSEND 5052//FOR SEND
#define BUFFER_LENGTH 1000
typedef struct
{
char ip[20];
char name[10];
bool in;
}CLIENT;
CLIENT clic[1000];
int ci=-1;
void main()
{
int iPort=DEFAULT_PORT;
WSADATA wsaData;
SOCKET sSocket;
int iLen;
int iSend;
int iRecv;
char send_buf[1000];
char recv_buf[BUFFER_LENGTH];
struct sockaddr_in ser,cli;
printf("----------------------\n");
printf("Server Waiting\n");
printf("----------------------\n");
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{printf("Failed to load Winsock.\n");return;}
sSocket=socket(AF_INET,SOCK_DGRAM,0);
if(sSocket==INVALID_SOCKET){printf("socket()Faild:%d\n",WSAGetLastError());return;}
ser.sin_family=AF_INET;
ser.sin_port=htons(iPort);
ser.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sSocket,(LPSOCKADDR)&ser,sizeof(ser))==SOCKET_ERROR)
{printf("bind()Faild:%d\n",WSAGetLastError());return;}
iLen=sizeof(cli);
memset(recv_buf,0,sizeof(recv_buf));
while(1)
{
//接收数据包 确定cli 表示 cli存有客户端发来的 ip和port
iRecv=recvfrom(sSocket,recv_buf,BUFFER_LENGTH,0,(SOCKADDR*)&cli,&iLen);
if(iRecv==SOCKET_ERROR)
{printf("recvfrom()Faild:%d\n",WSAGetLastError());return;}
else if(iRecv==0) break;
else
{// 接收到了正确数据
printf("recv:%s\n",recv_buf);
printf("Accepted client IP:[%s],port:[%d]\n",inet_ntoa(cli.sin_addr),ntohs(cli.sin_port));
//newuser newsays
char tempstr[1024];
strncpy(tempstr,recv_buf,7);
tempstr[7]='\0';
//printf("tempstr=%s\n",tempstr);
if(strcmp(tempstr,"newuser")==0)
{
printf("this is a new user\n");
ci++;
strcpy(clic[ci].name,recv_buf+7);
strcpy(clic[ci].ip,inet_ntoa(cli.sin_addr));
clic[ci].in=1;
}
else if(strcmp(tempstr,"newsays")==0)
{
printf("this is a new say\n");
int i;
for(i=0;i<=ci;i++)
{
if(clic[i].in==1 && strcmp(clic[i].ip,inet_ntoa(cli.sin_addr))==0)
{
printf("找到该用户,名字为%s\n",clic[i].name);
break;
}
}
if(i>ci){printf("未从服务器中找到该用户,发生错误!\n");}
if(strcmp("exit",recv_buf+7)==0)
{
clic[i].in=0;
}
else
{
strcpy(send_buf,clic[i].name);
strcat(send_buf,":");
strcat(send_buf,recv_buf+7);
int t;
for(t=0;t<=ci;t++)
{
if(clic[t].in==0 || t==i)continue;
cli.sin_addr.s_addr=inet_addr(clic[t].ip);
cli.sin_port=htons(DEFAULT_PORTSEND);
iSend=sendto(sSocket,send_buf,sizeof(send_buf),0,(SOCKADDR*)&cli,sizeof(cli));
printf("服务器已经向%s广播该信息:%s\n",clic[t].name,send_buf);
if(iSend==SOCKET_ERROR)
{
printf("sendto()Failed.:%d\n",WSAGetLastError());
break;
}
else if(iSend==0) break;
else
{
printf("sendto() succeeded !\n");
printf("----------------------\n");
}
}
}
}
else printf("recv error!\n");
}
}
closesocket(sSocket);
WSACleanup();
}
#include
#include
#include
#include
#include
#pragma comment(lib,"ws2_32.lib")
#define DEFAULT_PORT 5051//FOR SEND
#define DEFAULT_PORTRECV 5052 //FOR RECV
#define BUFFER_LENGTH 1024
struct P
{
SOCKET *sClient;
struct sockaddr_in *ser;
};
DWORD WINAPI ThreadProc1(LPVOID lpParam)
{
//printf("threadproc1 is running! ");
int iRecv;
char recv_buf[1030];
int iLen;
SOCKET sClient;
struct sockaddr_in ser;
sClient=*((struct P *)lpParam)->sClient;
ser=*((struct P *)lpParam)->ser;
iLen=sizeof(ser);
while(1)
{
iRecv=recvfrom(sClient,recv_buf,sizeof(recv_buf),0,(struct sockaddr*)&ser,&iLen);
if(iRecv==SOCKET_ERROR)
{printf("recvfrom()Failed.:%d\n",WSAGetLastError());return 0;}
else if(iRecv==0) return 0;
else
{
printf("\n----------------------\n");
//printf("Accepted client IP:[%s],port:[%d]\n",inet_ntoa(ser.sin_addr),ntohs(ser.sin_port));
printf("%s\n",recv_buf);
printf("----------------------\n");
printf("请输入内容:");
}
}
return 0;
}
void main(int argc,char *argv[])
{
WSADATA wsaData;
SOCKET sClient;
int iPort=DEFAULT_PORT;
int iLen;
int iSend;
int iRecv;
char send_buf[1000]="newuser";
char recv_buf[BUFFER_LENGTH];
struct sockaddr_in ser;
if(argc<2){printf("usage:client [server IP address]\n");return;}
memset(recv_buf,0,sizeof(recv_buf));
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
{
printf("Failed to load winsock.\n");
return ;
}
//建立服务器信息 发送到目标机器
ser.sin_family=AF_INET;
ser.sin_port=htons(iPort);
ser.sin_addr.s_addr=inet_addr(argv[1]);
sClient=socket(AF_INET,SOCK_DGRAM,0);
if(sClient==INVALID_SOCKET)
{printf("socket()Failed:%d\n",WSAGetLastError());return;}
iLen=sizeof(ser);
struct sockaddr_in cser;
cser.sin_family=AF_INET;
cser.sin_port=htons(DEFAULT_PORTRECV);
cser.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sClient,(LPSOCKADDR)&cser,sizeof(cser))==SOCKET_ERROR)
{printf("bind()Faild:%d\n",WSAGetLastError());return ;}
/*
cser.sin_family=AF_INET;
cser.sin_port=htons(iPort);
cser.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sSocket,(LPSOCKADDR)&ser,sizeof(ser))==SOCKET_ERROR)
{printf("bind()Faild:%d\n",WSAGetLastError());return;}
*/
char name[100];
printf("请输入您的姓名:");
scanf("%s",&name);
if(strcmp(name,"exit")==0)return;
strcat(send_buf,name);
iSend=sendto(sClient,send_buf,sizeof(send_buf),0,(struct sockaddr*)&ser,iLen);
//CreateThread(
// NULL, // default security attributes
// 0, // use default stack size
// (LPTHREAD_START_ROUTINE )ThreadProc1, // thread function
// argv[1], // argument to thread function
// 0, // use default creation flags
// (LPDWORD)&ThreadProc1); // returns the thread identifier
struct P * point;
point=(struct P *)malloc(sizeof(struct P));
point->sClient=&sClient;
point->ser=&ser;
CreateThread(
NULL, // default security attributes
0, // use default stack size
ThreadProc1, // thread function
(LPVOID)point, // argument to thread function
0, // use default creation flags
NULL); // returns the thread identifier
while(1)
{
char says[1000];
printf("请输入内容:");
scanf("%s",&says);
strcpy(send_buf,"newsays");
strcat(send_buf,says);
iSend=sendto(sClient,send_buf,sizeof(send_buf),0,(struct sockaddr*)&ser,iLen);
if(iSend==SOCKET_ERROR)
{printf("sendto()Failed:%d\n",WSAGetLastError());return;}
else if(iSend==0) return;
else
{
;//printf("sendto() mubiao succeeded .\n");
}
if(strcmp(says,"exit")==0){printf("exited!\n");break;}
/*
iRecv=recvfrom(sClient,recv_buf,sizeof(recv_buf),0,(struct sockaddr*)&ser,&iLen);
if(iRecv==SOCKET_ERROR)
{printf("recvfrom()Failed.:%d\n",WSAGetLastError());return;}
else if(iRecv==0) return;
else
{
printf("recvfrom():%s\n",recv_buf);
printf("----------------------\n");
}
*/
}
closesocket(sClient);
WSACleanup();
}