日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

step5 . day5 网络编程 基于UDP协议的多人网络在线聊天功能

發布時間:2024/4/17 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 step5 . day5 网络编程 基于UDP协议的多人网络在线聊天功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

模擬在線群聊功能,使用多進程完成聊天內容的接受和服務器端的轉發,demo代碼記錄參考

//client_chat_UDP code

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <linux/in.h>
#include <sys/select.h>
#include <signal.h>

#define N 128
typedef struct massage{
char type;
char name[32];
char buf[N];
}MSG;


int main(int argc, const char *argv[])
{
//判斷輸入、提示格式
if(argc<3){
printf("Usrmag:%s <server IP> <PORT>\n",argv[0]);
return -1;
}

//創建通信套接字 使用UDP通訊協議
int socket_fd;
socket_fd = socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd < 0){
perror("socket failed:");
return -1;
}
printf("socket ok\n");

//填充結構體
struct sockaddr_in serveraddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
serveraddr.sin_port = htons(atoi(argv[2]));

//定義發送接收緩存
MSG sendmsg,recvmsg;
printf("please input your name :");
fgets(sendmsg.name,32,stdin);
sendmsg.name[strlen(sendmsg.name)-1] = '\0';
sendmsg.type = 'L';
sprintf(sendmsg.buf,"%s login",sendmsg.name);
sendto(socket_fd, &sendmsg, sizeof(sendmsg),0,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
//創建多進程,一個用來接收,一個用來發送
int pid;
pid = fork();
if(pid < 0){
perror("fork failed:");
return -1;
}else if(pid == 0){
while(1){
printf("send msg>> ");
fgets(sendmsg.buf,N,stdin);
sendmsg.buf[strlen(sendmsg.buf)-1] = '\0';
if(strncmp(sendmsg.buf,"quit",4)!=0){
sendmsg.type = 'B';
sendto(socket_fd,&sendmsg,sizeof(sendmsg),0,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
printf("send ok.\n");
}
else{
sendmsg.type = 'Q';
sendto(socket_fd,&sendmsg,sizeof(sendmsg),0,(struct sockaddr*)&serveraddr,sizeof(serveraddr));
printf("offline.\n");
close(socket_fd);
kill(getppid(), SIGKILL);
return -1;
}
}
}else{
while(1){
recvfrom(socket_fd, &recvmsg, sizeof(recvmsg),0,NULL,NULL);
printf("\n%s said:%s\n",recvmsg.name,recvmsg.buf);
}
}

close(socket_fd);
return 0;
}

?

?

//server_chat_UDP code

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <linux/in.h>
#include <sys/select.h>
#include <stdlib.h>


#define N 128
//消息結構體
typedef struct massage{
char type;
char name[32];
char buf[N];
}MSG;

//登陸用戶鏈表
typedef struct node{
struct node *next;
char name[32];
struct sockaddr_in addr;
}linklist;

//模塊操作判斷函數
void login(int sockfd,MSG msg,struct sockaddr_in clientaddr,struct sockaddr_in serveraddr,linklist *head);
void quit(int sockfd,MSG msg,struct sockaddr_in serveraddr,linklist *head);
void broadcast(int socket_fd,MSG msg,linklist *head);

//鏈表創建函數
linklist * linklist_create(){

linklist *h = (linklist *)malloc(sizeof(linklist));
h->next = NULL;
return h;
}

int main(int argc, const char *argv[])
{
//判斷輸入、提示格式
if(argc<2){
printf("Usrmag:%s <PORT>\n",argv[0]);
return -1;
}

//創建通信套接字 使用UDP通訊協議
int socket_fd;
socket_fd = socket(AF_INET,SOCK_DGRAM,0);
if(socket_fd < 0){
perror("socket failed:");
return -1;
}
printf("socket ok\n");
//填充結構體
struct sockaddr_in serveraddr;
struct sockaddr_in clientaddr;
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(atoi(argv[1]));
socklen_t addrlen = sizeof(struct sockaddr_in);
socklen_t clientaddrlen = sizeof(struct sockaddr_in);
int bind_fd;
bind_fd = bind(socket_fd,(struct sockaddr*)&serveraddr,addrlen);
if(bind_fd < 0){
perror("bind failed:");
return -1;
}
printf("bind ok\n");

//定義發送接收緩存
MSG sendmsg,recvmsg;

//創建用戶鏈表表頭
linklist *head = linklist_create();

//創建多進程,一個用來接收,一個用來廣播
int pid;
pid = fork();
if(pid < 0){
perror("fork failed:");
return -1;
}else if(pid ==0){ //子進程用來客戶端的發送廣播
while(1){
strcpy(sendmsg.name,"server");
sendmsg.type = 'B';
fgets(sendmsg.buf,N,stdin);
sendmsg.buf[strlen(sendmsg.buf)-1] = '\0';
sendto(socket_fd,&sendmsg,sizeof(sendmsg),0,(struct sockaddr *)&serveraddr,addrlen);
}
}else{
//父進程接受客戶端發送消息
while(1){
recvfrom(socket_fd,&recvmsg,sizeof(recvmsg),0,(struct sockaddr *)&clientaddr,&clientaddrlen);

switch(recvmsg.type){
case 'L':
login(socket_fd,recvmsg,clientaddr,serveraddr,head);
break;
case 'B':
//服務器轉發
broadcast(socket_fd,recvmsg,head);
break;
case 'Q':
//退出
printf("quit wait :\n");
printf("%s said:%s\n",recvmsg.name,recvmsg.buf);
quit(socket_fd,recvmsg,serveraddr,head);
break;
}
}

}
close(socket_fd);
return 0;
}

void login(int sockfd,MSG msg,struct sockaddr_in clientaddr,struct sockaddr_in serveraddr,linklist *head){


printf("%s login\n",msg.name);
linklist *p = head;
while(p->next != NULL){
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&(p->next->addr),sizeof(serveraddr));
p = p->next;
}
linklist *temp = linklist_create();
strcpy(temp->name,msg.name);
temp->addr = clientaddr;

temp->next = NULL;
p->next = temp;
}

void quit(int sockfd,MSG msg,struct sockaddr_in serveraddr,linklist *head){

linklist *p = head;
while(strcmp(p->next->name,msg.name)!=0){
p = p->next;
}
linklist *temp = p->next;
p->next = temp->next;

sprintf(msg.buf,"%s offline",msg.name);
msg.type = 'B';
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&serveraddr,sizeof(serveraddr));

free(temp);
temp = NULL;
}
void broadcast(int sockfd,MSG msg,linklist *head){

printf("%s said:%s\n",msg.name,msg.buf);
linklist *temp = head->next;
while(temp != NULL){
if(strcmp(temp->name,msg.name) ==0){
temp = temp->next;
}
else{
sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr*)&(temp->addr),sizeof(temp->addr));
temp = temp->next;
}

}

}

轉載于:https://www.cnblogs.com/huiji12321/p/11378841.html

總結

以上是生活随笔為你收集整理的step5 . day5 网络编程 基于UDP协议的多人网络在线聊天功能的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。