C语言的UDP多线程点对点发送消息

windows下使用Dev C++调试

Server段:

/**
 * 编译命令:gcc udps.c -lws2_32 -lmycon -lwinmm -o us.exe
 */

#include 
#include 
#include 

struct sockaddr_in serveraddr;
struct sockaddr_in clientaddr;
int nclientaddrlen = sizeof(clientaddr);
char sendData[256];
char recvData[256];
SOCKET serversocket;
int isrunning = 1;

//接收消息的函数,单独一个线程中运行
void receive_msg()
{
	while (1)
    {
		//接收来自聊天对方的消息
        int ret = recvfrom(serversocket, recvData, 256, 0,  \
					(struct sockaddr *)&clientaddr, &nclientaddrlen);
        if (ret > 0)
        {
            recvData[ret] = '\0';					//填充字符串结束符'\0'
            printf("来自%s的新消息:%s\n", inet_ntoa(clientaddr.sin_addr), recvData); 
			
			//如果消息是bye,则退出聊天
			if (!strcmp(recvData, "bye"))
			{
				isrunning = 0;
				printf("系统退出!");
				
				return;
			}
        }
    }
}

int main(int argc, char* argv[])
{
	set_title("基于UDP的简单聊天程序服务器端");	//设置窗口标题
	set_size(80, 25);								//设置窗口为80 * 25
	cls();											//清屏
	printf("天天聊天室欢迎你!\n\n");

	//初始化动态链接库ws2_32.dll,协商版本
    WSADATA wsaData;
    WORD sockVersion = MAKEWORD(2, 2);
    if (WSAStartup(sockVersion, &wsaData) != 0)
    {
        return 0;
    }

	//创建套接字
    serversocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    if (serversocket == INVALID_SOCKET)
    {
        printf("Socket创建错误!");
        
		return 0;
    }

    //绑定协议、端口和地址
	serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(6666);			//将端口6666转换为网络字节序
    serveraddr.sin_addr.S_un.S_addr = INADDR_ANY;
    if (bind(serversocket, (struct sockaddr *)&serveraddr,  \
			sizeof(serveraddr)) == SOCKET_ERROR)
    {
        printf("绑定地址和端口错误!");
        
		closesocket(serversocket);
        
		return 0;
    }
   
	//启动接收消息线程
	_beginthread(receive_msg, 0, NULL);

    while (1)
    {
		if (!isrunning)
		{
			break;
		}

		//从键盘接收要发送的消息
		gets(sendData);

        //发送聊天消息
		sendto(serversocket, sendData, strlen(sendData), 0,  \
				(struct sockaddr *)&clientaddr, nclientaddrlen); 
		
		//如果是bye,则退出聊天
		if (!strcmp(recvData, "bye"))
		{
			isrunning = 0;
			printf("系统退出!");
			break;
		}
    }

	//结束接收消息的线程
	_endthread();

    //关闭套接字并清理释放相关资源
	closesocket(serversocket); 
    WSACleanup();

	return 0;
}

Client端:

/**
 * 编译命令:gcc udpc.c -lws2_32 -lmycon -lwinmm -o uc.exe
 */

#include 
#include 
#include 

struct sockaddr_in serveraddr;
int nserveraddrlen = sizeof(serveraddr);
SOCKET clientsocket;
char sendData[256];
char recvData[256];
int isrunning = 1;

//接收消息的函数,单独一个线程中运行
void receive_msg()
{
	while (1)
    {   
		//接收来自聊天对方的消息
        int ret = recvfrom(clientsocket, recvData, 256, 0,  \
					(struct sockaddr *)&serveraddr, &nserveraddrlen);
        if (ret > 0)
        {
            recvData[ret] = '\0';					//填充字符串结束符'\0'
            printf("来自%s的新消息:%s\n", inet_ntoa(serveraddr.sin_addr), recvData); 
			
			//如果消息是bye,则退出聊天
			if (!strcmp(recvData, "bye"))
			{
				isrunning = 0;
				printf("系统退出!");

				return;
			}
        }
    }
}

int main(int argc, char* argv[])
{
	set_title("基于UDP的简单聊天程序客户端");		//设置窗口标题
	set_size(80, 25);								//设置窗口为80 * 25
	cls();											//清屏
	printf("天天聊天室欢迎你!\n\n");

    //初始化动态链接库ws2_32.dll,协商版本
	WSADATA wsaData;
	WORD socketVersion = MAKEWORD(2, 2); 
    if (WSAStartup(socketVersion, &wsaData) != 0)
    {
        return 0;
    }

	//创建套接字
    clientsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    
    //绑定协议、端口和地址
	struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_port = htons(6666);//聊天端口
    server.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//聊天服务器IP地址
    int len = sizeof(server);

	//启动接收消息线程
	_beginthread(receive_msg, 0, NULL);
	
	while (1)
	{
		if (!isrunning)
		{
			break;
		}
		
		//从键盘接收要发送的消息
		gets(sendData);
		//发送聊天消息
		sendto(clientsocket, sendData, strlen(sendData), 0,  \
			(struct sockaddr *)&server, len);

		//如果是bye,则退出聊天
		if (!strcmp(recvData, "bye"))
		{
			isrunning = 0;
			printf("系统退出!");
			break;
		}
	}

	//结束接收消息的线程
	_endthread();

	//关闭套接字并清理释放相关资源
    closesocket(clientsocket);
    WSACleanup();

	return 0;
}

mycon.h(32位)

#ifndef _WINDOWS_H_
#define	_WINDOWS_H_
#endif

//改变控制台窗口大小为width宽,height高
void set_size(int width, int height);

//设置控制台窗口的标题为字符串title
void set_title(char *title);

//移动光标到坐标(x, y)处,即y行x列
void gotoxy(int x, int y); 

//隐藏光标
void hide_cursor(void);

//显示光标
void show_cursor(void);

//设置颜色函数: bcolor背景色,fcolor前景色 
//具体颜色值参见命令行下的color/?命令。
void set_color(int bcolor, int fcolor);

//延时函数,单位毫秒
void delay(int dtime);

//播放wav格式的声音
void play_sound(const char *sndfile);

//清屏
void cls(void);

//获取按键
int getkey(void);

mycon.h(64位)

#ifndef _WINDOWS_H_
#define	_WINDOWS_H_
#endif

//改变控制台窗口大小为width宽,height高
void set_size(int width, int height);

//设置控制台窗口的标题为字符串title
void set_title(char *title);

//移动光标到坐标(x, y)处,即y行x列
//假设窗口为25行80列,则左上角的字符坐标为(0, 0),右下角的字符坐标为(79, 24)
void gotoxy(int x, int y); 

//隐藏光标
void hide_cursor(void);

//显示光标
void show_cursor(void);

//设置颜色函数: bcolor背景色,fcolor前景色 
//具体颜色值参见命令行下的color/?命令。
void set_color(int bcolor, int fcolor);

//延时函数,单位毫秒
void delay(int dtime);

//播放wav格式的声音
void play_sound(const char *sndfile);

//清屏
void cls(void);

//获取按键
int getkey(void);

仅供学习

你可能感兴趣的:(c语言,udp)