1.数据报格式套接字
数据报格式套接字(代码为SOCK_DGRAM),采用此方法计算机只管发送数据而不去验证发送数据的正确性,不论传输是否被接收,数据流是否有丢失,都不再重新发送,特征如下:
1.强调快速传输而非传输顺序;
2.传输的数据可能丢失也可能损毁;
3.限制每次传输的数据大小;
4.数据的发送和接收是并发的。
总之,数据报套接字是一种不可靠的、不按顺序传递的、以追求速度为目的的套接字。
2.采用UDP协议
而数据报套接字采用的是(User Datagram Protocol)协议,本次聊天室采用UDP协议虽然可能会导致数据丢失,但是聊天并不去强调内容的正确性,而应该强调实时性,并且数据丢失只是小概率事件。
3.实现
流程: server 接收来自client的消息并转发给其他client, 并且自身也能发布公告
client 发送消息给server,接收来自server的信息(包括群发内容和公告)
server.c
在服务器定义了两个结构体,INFO,usr_list分别去接受客户端的信息和保存接入客户端的信息。
typedef int protocol; //自己定义的协议 1为用户登录信息 2为普通信息 3为退出信息
typedef struct{
char name[13]; //用户昵称(自定义)
char msg[64]; //正文内容
protocol P; //协议
}INFO;
typedef struct usr_list{
struct sockaddr_in usr_addr; //保存接入用户的信息
struct usr_list *next; //指针
}usr_node,*List;
代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
typedef int protocol; //自定义协议 1登录信息 2普通信息 3退出信息
typedef struct sockaddr_in IN;
int len_s = sizeof(struct sockaddr_in);
IN serv_addr,clnt_addr;
typedef struct{
char name[13];
char msg[64];
protocol P;
}INFO;
int len_info = sizeof(INFO);
typedef struct usr_list{
IN usr_addr;
struct usr_list *next;
}usr_node,*List;
List list; //创建用户链表为全局变量,之后利用线程分别实现接收转发消息和server自身发送消息
void init(); //初始化用户链表
void get_len();//得到链表长度(在测试时用,本例子无实际意义)
void insert_node(IN usr_addr); //插入节点
void del_node(IN usr_addr); //删除节点
void send_log(int serv_fd,INFO info,IN clnt_addr); //发送登录信息
void send_msg(int serv_fd,INFO info,IN clnt_addr); //发送普通信息
void send_off(int serv_fd,INFO info,IN clnt_addr); //发送离线信息
void serv_send(int serv_fd,char *buf); //server发送消息
voi