C语言-Windows网络编程-实验 TCP网络通信器的设计:服务器和客户端 一个简易的即时聊天工具

RT。。。就是网络编程课的任务啊、
写了一个服务器与客户端的控制台程序,实现一来一回的即时聊天,可显示发送时间,以关键字bye结束连接
遗憾的是也只能一来一回,不能某端连续发送消息
在执行监听函数的时候就不能执行输入,或者这就是黑屏程序吧…
查了下貌似其实也能做到,利用多线程?不过现在没去找资料学习了
明天就是上机课,这个实验一任务截止,先把代码po到博客里。

服务器端

#include 
#include 
#include 
#include 
#pragma comment (lib,"Ws2_32.lib")

#define NUM 10		// 最大客户端连接数

void END(SOCKET &ListenSocket,SOCKET &ClientSocket)			// 释放相关资源
{
	closesocket(ListenSocket);
	closesocket(ClientSocket);
	WSACleanup();
}

void OutputTime()
{
	time_t T;
	struct tm *p;
	time (&T);
	p = localtime(&T);
	printf("%d/%02d/%02d %02d:%02d:%02d\n\n",1900+p->tm_year,1+p->tm_mon,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
}

int main()
{
	system("title 服务器端");
	system("mode con cols=49 lines=30");
	
	char servername[100]={"Server"};			// 存储服务器名称
	char clientname[100]={0};
	WSADATA wsaData;
	char buf[100]={0};        //发送数据缓冲区
	char getbuf[100]={0};     //接收数据缓冲区// 创建类型为WSADATA的对象

	int iResult = WSAStartup(MAKEWORD(2,2),&wsaData);			// 初始化winsock并根据返回值判断错误信息
	if(iResult!=0)
	{
		printf("初始化失败。错误代码:%d\n",iResult);
		return 1;
	}

	SOCKET ListenSocket,ClientSocket;						// 定义监听和通信套接字
	ListenSocket = socket(AF_INET,SOCK_STREAM,0);			// 定义此Socket所使用的通信协议:IPV4地址族、流式套接字、不指定通信协议

	sockaddr_in addr,addr2;									// 定义套接字地址结构
	addr.sin_family = AF_INET;								// 初始化地址结构
	addr.sin_port = htons(75);
	addr.sin_addr.S_un.S_addr = INADDR_ANY;

	int addr2Len = sizeof(addr2);							// 获取套接字地址结构大小

	bind(ListenSocket, (sockaddr*)&addr, sizeof(addr) );	// 绑定套接字
	listen(ListenSocket,NUM);								// 监听套接字,最大连接数为10


	if(iResult==0)
	{
		printf("服务器初始化完成\n");
		
	}

	char str[] = "\n正在等待客户端连接...\n";
	for(int i=0;str[i]!='\0';i++)							// 以打字机效果输出等待提示信息
	{
		printf("%c",str[i]);
		Sleep(35);
	}

	ClientSocket = accept(ListenSocket, (sockaddr*)&addr2, &addr2Len);		// 服务器端接受客户端的连接请求

	if(ClientSocket != NULL)
	{
		printf("  客户端已连接至服务器,客户端IP:%s\n", inet_ntoa(addr2.sin_addr) );
		
	}
	
	iResult=send(ClientSocket,servername,sizeof(servername),0);      // 发送服务器名称至客户端
	if(iResult==SOCKET_ERROR)
	{
		printf("\n  连接至客户端失败,连接断开...\n");
		END(ListenSocket,ClientSocket);
		return 1;
	}
		
	iResult=recv(ClientSocket,clientname,sizeof(clientname),0);   // 接收客户端名称
	if(iResult==SOCKET_ERROR)
	{
		printf("\n  客户端通讯返回失败,连接断开...\n");
		END(ListenSocket,ClientSocket);
		return 1;
	}

	printf("\n---输入需要发送的信息,键入关键词bye以结束会话---\n\n");
	char wait[]="[正在输入...]";

	while(1)  // 持续发送接收消息
	{
		printf("%s:",servername);
		gets(buf);
		OutputTime();
		iResult=send(ClientSocket,buf,sizeof(buf),0);	// 向客户端发送信息,函数调用方式与write()无异
		if(iResult==SOCKET_ERROR)
		{
			printf("----------------连接断开,发送失败---------------\n\n");
			END(ListenSocket,ClientSocket);
			break;
		}
		if(strcmp(buf,"bye")==0)
		{
			printf("------------------您已结束会话-------------------\n\n");
			END(ListenSocket,ClientSocket);
			break;
		}
		memset(buf,0,sizeof(buf));
		printf("%s:%s",clientname,wait);


		iResult=recv(ClientSocket,getbuf,sizeof(getbuf),0);   // 接收数据
	    if(iResult==SOCKET_ERROR)
		{
			printf("  接收失败,连接断开...\n");
			printf("----------------连接断开,接收失败---------------\n\n");
			END(ListenSocket,ClientSocket);
			break;
		}
		printf("\r%s:%s             \n",clientname,getbuf);
		OutputTime();

		if(strcmp(getbuf,"bye")==0)
		{
			printf("----------------对方结束了会话-------------------\n\n");
			END(ListenSocket,ClientSocket);
			break;
		}
		memset(getbuf,0,sizeof(getbuf));
	}
    return 0;
}

客户端

#include 
#include 
#include 
#include 
#pragma comment (lib,"Ws2_32.lib")

#define TIMES 7		// 最大重连次数

void END(SOCKET &s)			// 释放相关资源
{
	closesocket(s);
	WSACleanup();
}

void OutputTime()
{
	time_t T;
	struct tm *p;
	time (&T);
	p = localtime(&T);
	printf("%d/%02d/%02d %02d:%02d:%02d\n\n",1900+p->tm_year,1+p->tm_mon,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
}

int main()
{
	system("title 客户端");
	system("mode con cols=49 lines=30");
	
	char servername[100]={0};		// 存储发送给客户端的信息
	char clientname[100]={"Client"};
	WSADATA data;        
	char buf[100]={0};        //发送数据缓冲区
	char getbuf[100]={0};     //接收数据缓冲区

	int iResult = WSAStartup(MAKEWORD(2,2),&data);
	if(iResult!=0)
	{
		printf("初始化版本号失败!");
		return -1;
	}

	SOCKET s;                           //创建套接字
	s=socket(AF_INET,SOCK_STREAM,0);
	if(s==INVALID_SOCKET)
	{
		printf("  创建套接字失败...\n");
		return 0;
	}

	sockaddr_in addr;                  //定义套接字地址结构
	addr.sin_family=AF_INET;           //初始化地址结构
	addr.sin_port=htons(75);
	addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

	printf("客户端初始化完成\n");

	char str[] = "\n正在连接服务器...";
	for(int i=0;str[i]!='\0';i++)							// 以打字机效果输出等待提示信息
	{
		printf("%c",str[i]);
		Sleep(35);
	}

	int TRY=0;								// 初始化连接次数
	while(1)								// 反复连接服务器直到成功或达到最大次数
	{
		iResult=connect(s,(sockaddr*)&addr,sizeof(addr));   // 连接服务器
		if(iResult==SOCKET_ERROR && TRY>=TIMES)
		{
			printf("\n  连接服务器失败!\n");
			return 1;
		}
		else if(iResult==SOCKET_ERROR)
		{
			TRY++;
			printf("\r连接失败!正在尝试重连...(%d/%d)",TRY,TIMES);
			Sleep(1000);				// 1秒后再次重连
		}
		else if(iResult==0)
		{
			printf("\n  客户端已成功与服务器建立通讯\n");
			break;
		}
	}

	iResult=recv(s,servername,sizeof(servername),0);   // 接收服务器名称
	if(iResult==SOCKET_ERROR)
	{
		printf("  接收服务器数据失败,连接断开...\n");
		return 1;
	}	

	iResult=send(s,clientname,sizeof(clientname),0);      // 发送客户端名称至服务端
	if(iResult==SOCKET_ERROR)
	{
		printf("  发送数据失败,连接断开...n");
		return 1;
	}

	printf("\n---输入需要发送的信息,键入关键词bye以结束会话---\n\n");
	char wait[]="[正在输入...]";

	while(1)
	{
		printf("%s:%s",servername,wait);
		iResult=recv(s,getbuf,sizeof(getbuf),0);   // 接收数据
		if(iResult==SOCKET_ERROR)
		{
			printf("\n\n---------------与服务器的连接断开----------------\n\n");
			END(s);
			break;
		}
		printf("\r%s:%s             \n",servername,getbuf);
		OutputTime();
		if(strcmp(getbuf,"bye")==0)
		{
			printf("----------------对方结束了会话-------------------\n\n");
			END(s);
			break;
		}
		memset(getbuf,0,sizeof(getbuf));

		printf("%s:",clientname);
		gets(buf);
		OutputTime();
		iResult=send(s,buf,sizeof(buf),0);
		if(iResult==SOCKET_ERROR)
		{
			printf("----------------连接断开,发送失败---------------\n\n");
			END(s);
			break;
		}
		if(strcmp(buf,"bye")==0)
		{
			printf("------------------您已结束会话-------------------\n\n");
			END(s);
			break;
		}
		memset(buf,0,sizeof(buf));
	}
	return 0;
}

你可能感兴趣的:(C/C++)