资源简介

Linux下基于UDP的socket编程,适用多客户端之间,服务器与客户端之间的通信。客户端和服务端代码分开了。notepad++可打开

资源截图

代码片段和文件信息

#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include “list.h“
#include 
#include 
#define SIZE_BUFF 1024

//标识客户端的结构体
struct udp_client
{
//客户端IP、端口信息
struct sockaddr_in cli;

//用于判断客户端是否在线的计数器,此计数器1s左右减一次
//减到0s代表客户端断开了连接(UDP客户端30s没有与服务器通信就认为断开了)当有消息到来时该计数器置为30s.
unsigned char time_count;

//客户端名字
char name[50];

//其对端客户端的节点地址
struct udp_client *target_node;

//内核链表
struct list_head kernel_list;
};
pthread_mutex_t mutex;
void * delete_client(void *p);
struct udp_client * head;
struct udp_client * get_node(struct sockaddr_in *cli);
int main(void)
{

int serfd = -1;
serfd = socket(AF_INETSOCK_DGRAM0);
if(serfd <0)
{
perror(“socket“);
exit(1);
}

//设置服务器(本机)IP的端口
struct sockaddr_in ser;
bzero(&sersizeof(ser));

ser.sin_family = AF_INET; 
//端口为6666
ser.sin_port   = htons(6666);
//IP为自动(本机网卡IP)
inet_pton(AF_INET“0.0.0.0“&ser.sin_addr);

if(bind(serfd(struct sockaddr *)&sersizeof(ser))<0)
{
perror(“bind“);
exit(1);
}

struct sockaddr_in cli;
bzero(&clisizeof(cli));
int len = sizeof(cli);
char buf[SIZE_BUFF];

int ret =-1;

//定义头节点并申请空间
head = (struct udp_client*)malloc(sizeof(struct udp_client));

if(NULL == head)
{
perror(“malloc“);
exit(1);
}
//链表头节点初始化
INIT_LIST_HEAD(&head->kernel_list);

//遍历链表相关的定义
struct list_head *pos=NULL*n=NULL;
struct udp_client* p_max_struct;
pthread_mutex_init(&mutexNULL);
pthread_t thread;
ret=pthread_create(&threadNULLdelete_clientNULL);
if(ret!=0)
{
perror(“pthread_creat“);
}
if(pthread_detach(thread)!=0)
{
perror(“pthread_detach“);
}

while(1)
{
bzero(bufSIZE_BUFF);
//接收数据没有数据来的话会阻塞等待
ret = recvfrom(serfdbufSIZE_BUFF0(void *)&cli&len);
if(ret <0)
{
perror(“recvfrom“);
exit(1);
}
//客户端登陆请求
if(!strncmp(“IM_LOGIN:“buf9))
{
bool user_name_ok_flag = true;
//判断用户名是否已经存在
pthread_mutex_lock(&mutex);
list_for_each_safe(posn&head->kernel_list)
{
//获取当前正在遍历的节点
p_max_struct=list_entry(posstruct udp_clientkernel_list);
if(!(strncmp(p_max_struct->namebuf+9ret-9-1)))
{
//用户名重复
ret = sprintf(buf“登陆失败:%s\n““用户名重复“);
ret = sendto(serfdbufret0(const struct sockaddr *)&clilen);
user_name_ok_flag = false;
break;
}
}
pthread_mutex_unlock(&mutex);
if(user_name_ok_flag)
{
//申请一个节点存储请求连接的客户端的信息
struct udp_client *p = (struct udp_client*)malloc(sizeof(struct udp_client));

if(NULL == p)
{
perror(“malloc“);
exit(1);
}

memset(p0sizeof(struct udp_client));
//保存客户端的信息到链表中
p->cli = cli;
p->target_node = NULL;
p->time_

评论

共有 条评论