基于udp協議的。要求就像我們正常聊天一樣,客戶端可以連續給服務器發多條資訊。感激不盡!
uj5u.com熱心網友回復:
#include<stdio.h>#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<string.h>
#include<signal.h>
struct msg
{
char type;
char name[15];
char buf[128];
};
typedef struct node
{
struct sockaddr_in data;
struct node *next;
}listnode;
listnode *create_head()
{
listnode *H;
H = malloc(sizeof(listnode));
H->next = NULL;
return H;
}
void do_login(listnode *H,struct sockaddr_in cliaddr,int sockfd,struct msg info)
{
listnode *p = H->next;
while(p != NULL)
{
if(memcmp(&cliaddr,&p->data,sizeof(cliaddr)) != 0)
sendto(sockfd,&info,sizeof(info),0,(struct sockaddr *)&p->data,sizeof(p->data));
p = p->next;
}
p = malloc(sizeof(listnode));
p->data = cliaddr;
p->next = H->next;
H->next = p;
}
void do_sendmsg(listnode *H,struct sockaddr_in cliaddr,int sockfd,struct msg info)
{
listnode *p = H->next;
while(p != NULL)
{
if(memcmp(&cliaddr,&p->data,sizeof(cliaddr)) != 0)
sendto(sockfd,&info,sizeof(info),0,(struct sockaddr *)&p->data,sizeof(p->data));
p = p->next;
}
}
void do_quit(listnode *H,struct sockaddr_in cliaddr,int sockfd,struct msg info)
{
listnode *p = H;
listnode *q;
while(p->next != NULL)
{
if(memcmp(&cliaddr,&p->next->data,sizeof(cliaddr)) == 0)
{
q = p->next;
p->next = q->next;
free(q);
}
else
{
sendto(sockfd,&info,sizeof(info),0,(struct sockaddr *)&p->next->data,sizeof(p->next->data));
p = p->next;
}
}
}
int main(int argc, const char *argv[])
{
int sockfd;
listnode *H;
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd == -1)
{
perror("socket");
exit(EXIT_FAILURE);
}
struct sockaddr_in seraddr,cliaddr;
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(50000);
seraddr.sin_addr.s_addr = inet_addr("192.168.1.250");
bind(sockfd,(struct sockaddr *)&seraddr,sizeof(seraddr));
struct msg info;
int clilen = sizeof(cliaddr);
H = create_head();
while(1)
{
recvfrom(sockfd,&info,sizeof(info),0,(struct sockaddr *)&cliaddr,&clilen);
switch(info.type)
{
case 'L':
do_login(H,cliaddr,sockfd,info);
break;
case 'S':
do_sendmsg(H,cliaddr,sockfd,info);
break;
case 'Q':
do_quit(H,cliaddr,sockfd,info);
break;
}
}
close(sockfd);
return 0;
}
uj5u.com熱心網友回復:
上面是服務器部分uj5u.com熱心網友回復:
int main(int argc, const char *argv[])
{
int sockfd;
pid_t pid;
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(sockfd == -1)
{
perror("socket");
exit(EXIT_FAILURE);
}
struct sockaddr_in seraddr,cliaddr;
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(50000);
seraddr.sin_addr.s_addr = inet_addr("192.168.1.250");
struct msg info;
info.type = 'L';
printf("請輸入登錄名:");
fgets(info.name,sizeof(info.name),stdin);
info.name[strlen(info.name) - 1] = '\0';
sendto(sockfd,&info,sizeof(info),0,(struct sockaddr *)&seraddr,sizeof(seraddr));
pid = fork();
if(pid == -1)
{
}
else if(pid == 0)
{
while(1)
{
printf("請發言:");
fgets(info.buf,sizeof(info.buf),stdin);
info.buf[strlen(info.buf) - 1] = '\0';
if(strncmp(info.buf,"quit",4) == 0)
{
info.type = 'Q';
sendto(sockfd,&info,sizeof(info),0,(struct sockaddr *)&seraddr,sizeof(seraddr));
kill(getppid(),SIGKILL);
exit(EXIT_SUCCESS);
}
else
{
info.type = 'S';
sendto(sockfd,&info,sizeof(info),0,(struct sockaddr *)&seraddr,sizeof(seraddr));
}
}
}
else
{
while(1)
{
recvfrom(sockfd,&info,sizeof(info),0,NULL,NULL);
switch(info.type)
{
case 'L':
printf("%s上線\n",info.name);
break;
case 'S':
printf("%s說:%s\n",info.name,info.buf);
break;
case 'Q':
printf("%s下線\n",info.name);
break;
}
}
}
close(sockfd);
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/112602.html
標籤:網絡通信
