基于socket的一个客户端与一个服务器程序,服务器端能实现同时接收多个客户端的消息。
使用C语言,socket技术,利用socket进行端口绑定与监听,实现消息收发。
代码:
服务器
#include "stdafx.h"
#include<stdio.h>
#include<winsock.h>
#include<windows.h>
#pragma comment(lib,"wsock32.lib")
#define BUF_SIZE 64
DWORD WINPAI thread1(LPVOID IpParameter);
SOCKET sockConn;
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
int retVal;
char buf[BUF_SIZE];
char msg[BUF_SIZE]="Receive Successfully";
int mode=1;
//初始化
if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0){
printf("WSAStartup无法初始化");
return 0;
}
//创建用于监听的对象
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
if(sockSrv==INVALID_SOCKET){
printf("SOCKET ERROR!");
return 0;
}
retVal=ioctlsocket(sockSrv,FIONBIO,(u_long FAR*)&mode);
if(SOCKET_ERROR==retVal)
{
printf("ioctlsocket failed ! \n");
WSACleanup();
return -1;
}
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(9000);
if(SOCKET_ERROR==bind(sockSrv,(const struct SOCKADDR*)&addrSrv,sizeof(SOCKADDR_IN))){
return -1;
}
listen(sockSrv,20);
printf("服务器就绪,等待客户端消息...");
sockaddr_in addrConn;
int addrConnLen=sizeof(addrConn);
while(true)
{
sockSrv=accept(sockSrv,(sockaddr FAR*)&addrConn,&addrConnLen);
if(INVALID_SOCKET == sockSrv)
{
int error = WSAGetLastError();
if(error == WSAEWOULDBLOCK)
{
Sleep(100);
continue;
}
}
printf(" [%s] Connects!\n",inet_ntoa(addrConn.sin_addr));
//创建线程
DWORD Thread;
CreateThread(NULL,NULL,thread1,(LPVOID)sockConn,0,&Thread);
//释放资源
closesocket(sServer);
closesocket(sClient);
WSACleanup();
//暂停,按任意键退出
system("pause");
return 0;
}
DWORD WINPAI thread1(LPVOID IpParameter)
{
SOCKET sockConn=(SOCKET)(LPVOID)IpParameter;
//发送接收数据
while(true){
int retVal;
char buf[BUF_SIZE];
char msg[BUF_SIZE]="Receive Successfully";
SOCKADDR_IN addrConn;
int addrLen=sizeof(addrConn);
getpeername(sockConn,(SOCKADDR*)&addrConn,&addrLen);
ZeroMemory(buf,BUF_SIZE);
retVal=recv(sockConn,buf,BUF_SIZE,0);
if(retVal==SOCKET_ERROR){
int error=WSAGetLastError();
if(error==WSAWOUDBLOCK){
Sleep(100);
continue;
}
else if(error==WSATIMEOUT||error==WSANETDOWN)
{
printf("receive failure");
closesocket(sockConn);
WSACleanup();
return -1;
}
}
if(strcmp(buf,"quit")==0){
printf("Connection [%s] finished\n",inet_ntoa(addrConn.sin_addr));
break;
}
printf("[%s] sends message:%s\n",inet_ntoa(addrConn.sin_addr),buf);
retVal=send(sockConn,msg,strlen(msg),0);
if(retVal==SOCKET_ERROR){
printf("sending failure");
closesocket(sockConn);
WSACleanup();
return -1;
}
}
}
客户端:
#include<stdio.h>
#include<windows.h>
#include<winsock.h>
#include<time.h>
#include<string>
#include<iostream>
#define BUF_SIZE 64
#pragma comment(lib,"wsock32.lib")
int _tmain(argc,_TCHAR* argv[])
{
WSADATA wsaData;
SOCKET sHost;
SOCKADDR_IN servAddr;
char buf[BUF_SIZE];
int retVal;
if(WSAStartup(MAKEWORD(2,2)&wsaData)!=0){
printf("WSAStratup error");
return 1;
}
sHost=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(INVALID_SOCKET==sHost)
{
printf("socket failure");
WSACleanup();
return -1;
}
servAddr.sin_family=AF_INET;
servAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
servAddr.sin_port=htons(9000);
retVal=connect(sHost,(LPSOCKADDR)&servAddr,sizeof(servAddr));
if(retVal==SOCKET_ERROR)
{
printf("connection fialed");
WSACleanup();
return -1;
}
while(true)
{
ZeroMemory(buf,BUF_SIZE);
printf("Sending message:\n");
gets(buf);
retVal = send(sHost,buf,strlen(buf),0);
if(SOCKET_ERROR == retVal)
{
printf("send failed ! \n");
closesocket(sHost);
WSACleanup();
return -1;
}
if(strcmp(buf,"quit") == 0)
{
printf("Finished Connecting. Closing socket.\n");
break;
}
else
{
retVal = recv(sHost,buf,BUF_SIZE,0);
if(SOCKET_ERROR == retVal)
{
printf("recv failed ! \n");
closesocket(sHost);
WSACleanup();
return -1;
}
printf("%s\n",buf);
}
}
//释放资源
closesocket(sHost);
WSACleanup();
//暂停,按任意键退出
system("pause");
return 0;
}