标签:
//***********服务端*******************
1 #include <head.h> 2 3 #define CLIENT_LOGIN 10 4 #define CLIENT_QUIT 20 5 #define CLIENT_TALK 30 6 #define SYSTEM_TALK 40 7 #define SYSTEM_QUIT 50 8 //#define CLIENT_PRIVATE 60 9 10 typedef struct 11 { 12 int msg_type; //消息类型 13 char client_name[20];//存放客户端用户名 14 char msg_buf[1024]; 15 //char peer_name[20]; 16 }msg_t; 17 18 //给套接字类型取一个别名 19 typedef struct sockaddr DATATYPE; 20 21 //创建节点 22 typedef struct node{ 23 DATATYPE data; //数据类型是struct sockaddr,即套接字结构的数据 24 //char client_name[20]; 25 struct node *next; 26 }LinkNode; 27 28 //用于线程的传参,因为线程构造函数只有一个参数,如果要传多个参数,可以构造一个结构体 29 typedef struct 30 { 31 int sockfd; 32 LinkNode *head; 33 }arg_t; 34 35 //创建空链表 36 LinkNode *create_empty_linklist() 37 { 38 LinkNode *head; 39 40 head = (LinkNode *)malloc(sizeof(*head)); 41 if(!head){ 42 fprintf(stderr,"%s : fail to malloc : %s\n",__FUNCTION__,strerror(errno)); 43 exit(EXIT_FAILURE); 44 } 45 head->next = NULL; 46 47 return head; 48 } 49 50 //链表的插入 51 int insert_linklist(LinkNode *head,DATATYPE data) 52 { 53 LinkNode *temp; 54 55 temp = (LinkNode *)malloc(sizeof(LinkNode)); 56 if(!temp){ 57 fprintf(stderr,"%s : fail to malloc : %s\n",__FUNCTION__,strerror(errno)); 58 exit(EXIT_FAILURE); 59 } 60 temp->data = data; 61 62 temp->next = head->next;//头插 head a 63 head->next = temp; // head temp a 64 65 return 0; 66 } 67 68 int find_linklist(LinkNode *head,DATATYPE data) 69 { 70 LinkNode *p; 71 72 for(p = head->next; p != NULL;p = p->next){ //遍历,p指针移动 73 74 if(memcmp(&(p->data),&data,sizeof(DATATYPE)) == 0){ // ??找到插入链表的套接字 75 return 1; 76 } 77 } 78 79 return 0; 80 } 81 82 //初始化服务端套接字 83 int init_udp_server_socket(const char *ip,const char *port) 84 { 85 int ret; 86 int sockfd; 87 struct sockaddr_in server_addr; 88 89 sockfd = socket(AF_INET,SOCK_DGRAM,0); 90 if(sockfd < 0){ 91 perror("Fail to socket"); 92 exit(EXIT_FAILURE); 93 } 94 95 server_addr.sin_family = AF_INET; 96 server_addr.sin_port = htons(atoi(port)); 97 server_addr.sin_addr.s_addr = inet_addr(ip); 98 ret = bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr)); //绑定服务端ip,port,结构体本 身不能直接强转
99 if(ret < 0){ 100 perror("Fail to bind"); 101 exit(EXIT_FAILURE); 102 } 103 104 return sockfd;//返回填充好的套接字描述符 105 } 106 107 //删除节点 108 int delete_linklist(LinkNode *head,DATATYPE data) 109 { 110 LinkNode *p; 111 LinkNode *q; 112 113 p = head->next; 114 q = head; 115 // q p 116 //head 1 2 3 4 5 0 117 while(p != NULL){ 118 if(memcmp(&(p->data),&data,sizeof(DATATYPE)) == 0){//遍历,找到删除的节点,则跳出循环 119 break; 120 }else{ 121 p = p->next;//指针移动 122 q = q->next; 123 } 124 } 125 126 if(p != NULL){ 127 q->next = p->next;//执行删除操作 128 free(p); 129 } 130 131 return 0; 132 } 133 134 //广播??? 135 void broadcast_message(int sockfd,LinkNode *head,msg_t *pmsg,int len) 136 { 137 int n; 138 LinkNode *p = NULL; 139 140 for(p = head->next; p != NULL;p = p->next) 141 { 142 n = sendto(sockfd,pmsg,len,0,&(p->data),sizeof(struct sockaddr)); 143 if(n < 0){ 144 perror("Fail to sendto"); 145 exit(EXIT_FAILURE); 146 } 147 } 148 149 return; 150 } 151 152 //主机接收消息 153 void recv_udp_message(int sockfd,LinkNode *L) 154 { 155 int n; 156 msg_t msg; 157 struct sockaddr_in peer_addr; 158 socklen_t addrlen = sizeof(struct sockaddr); 159 160 while(1) 161 { 162 n = recvfrom(sockfd,&msg,sizeof(msg),0,(struct sockaddr *)&peer_addr,&addrlen); 163 if(n < 0){ 164 perror("Fail to recvfrom"); 165 exit(EXIT_FAILURE); 166 } 167 168 printf("--------------------------------------------\n"); 169 printf("Ip : %s\n",inet_ntoa(peer_addr.sin_addr)); 170 printf("Port : %d\n",htons(peer_addr.sin_port)); 171 printf("Recv %d bytes : %s\n",n,msg.msg_buf); 172 printf("--------------------------------------------\n"); 173 174 switch(msg.msg_type) 175 { 176 case CLIENT_LOGIN: 177 insert_linklist(L,*(struct sockaddr *)&peer_addr); 178 break; 179 180 case CLIENT_QUIT: 181 delete_linklist(L,*(struct sockaddr *)&peer_addr); 182 break; 183 184 case CLIENT_TALK: 185 break; 186 } 187 broadcast_message(sockfd,L,&msg,sizeof(msg)); 188 } 189 190 return ; 191 } 192 193 //???子线程 194 void *send_udp_mssage(void *arg) 195 { 196 msg_t msg; 197 int sockfd = ((arg_t *)arg)->sockfd; 198 LinkNode *head = ((arg_t *)arg)->head; 199 200 while(1) 201 { 202 printf("input>"); 203 msg.msg_type = SYSTEM_TALK; 204 strcpy(msg.client_name,"system"); 205 206 fgets(msg.msg_buf,sizeof(msg.msg_buf),stdin); 207 msg.msg_buf[strlen(msg.msg_buf) - 1]= ‘\0‘; 208 209 if(strncmp(msg.msg_buf,"quit",4) == 0) 211 goto next; 212 213 broadcast_message(sockfd,head,&msg,sizeof(msg)); 214 } 215 216 next: 217 msg.msg_type = SYSTEM_QUIT; 218 broadcast_message(sockfd,head,&msg,sizeof(msg)); 219 exit(EXIT_SUCCESS); 220 } 221 222 //./udp_server ip port 223 int main(int argc, const char *argv[]) 224 { 225 int ret; 226 int sockfd; 227 arg_t thread_arg; 228 pthread_t tid; 229 LinkNode *L = create_empty_linklist(); 230 231 if(argc < 3){ 232 fprintf(stderr,"Usage : %s <ip> <port>\n",argv[0]); 233 return -1; 234 } 235 236 sockfd = init_udp_server_socket(argv[1],argv[2]); 237 238 thread_arg.sockfd = sockfd; 239 thread_arg.head = L; 240 ret = pthread_create(&tid,NULL,send_udp_mssage,&thread_arg);//子线程负责发送消息 241 242 recv_udp_message(sockfd,L); 243 244 return 0; 245 }
//************客户端**************
1 #include <head.h> 2 3 #define CLIENT_LOGIN 10 4 #define CLIENT_QUIT 20 5 #define CLIENT_TALK 30 6 #define SYSTEM_TALK 40 7 #define SYSTEM_QUIT 50 8 9 typedef struct 10 { 11 int msg_type; 12 char client_name[20]; 13 char msg_buf[1024]; 14 }msg_t; 15 16 int init_udp_client_socket(const char *ip,const char *port) 17 { 18 int ret; 19 int sockfd; 20 struct sockaddr_in client_addr; 21 22 sockfd = socket(AF_INET,SOCK_DGRAM,0); 23 if(sockfd < 0){ 24 perror("Fail to socket"); 25 exit(EXIT_FAILURE); 26 } 27 28 if(ip != NULL && port != NULL){ 29 30 client_addr.sin_family = AF_INET; 31 client_addr.sin_port = htons(atoi(port)); 32 client_addr.sin_addr.s_addr = inet_addr(ip); 33 ret = bind(sockfd,(struct sockaddr *)&client_addr,sizeof(client_addr)); 34 if(ret < 0){ 35 perror("Fail to bind"); 36 exit(EXIT_FAILURE); 37 } 38 } 39 40 return sockfd; 41 } 42 43 void send_udp_message(int sockfd,const char *peer_ip,const char *peer_port,const char *client_name) 44 { 45 int n; 46 msg_t msg; 47 struct sockaddr_in peer_addr; 48 socklen_t addrlen = sizeof(struct sockaddr); 49 50 peer_addr.sin_family = AF_INET; 51 peer_addr.sin_port = htons(atoi(peer_port)); 52 peer_addr.sin_addr.s_addr = inet_addr(peer_ip); 53 54 //send login message 55 msg.msg_type = CLIENT_LOGIN; 56 strcpy(msg.client_name,client_name); 57 strcpy(msg.msg_buf,"I am login!"); 58 59 n = sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr *)&peer_addr,addrlen); 60 if(n < 0){ 61 perror("Fail to sendto"); 62 exit(EXIT_FAILURE); 63 } 64 65 while(1) 66 { 67 printf("input>"); 68 msg.msg_type = CLIENT_TALK; 69 70 fgets(msg.msg_buf,sizeof(msg.msg_buf),stdin); 71 msg.msg_buf[strlen(msg.msg_buf) - 1]= ‘\0‘; 72 73 n = sendto(sockfd,&msg,sizeof(msg),0,(struct sockaddr *)&peer_addr,addrlen); 74 if(n < 0){ 75 perror("Fail to sendto"); 76 exit(EXIT_FAILURE); 77 } 78 79 printf("Send %d bytes : %s\n",n,msg.msg_buf); 80 81 if(strncmp(msg.msg_buf,"quit",4) == 0) 82 break; 83 } 84 85 return ; 86 } 87 88 void thread_recv_udp_message(void *arg) 89 { 90 int n; 91 msg_t msg; 92 int sockfd = *(int *)arg; 93 struct sockaddr_in peer_addr; 94 socklen_t addrlen = sizeof(struct sockaddr); 95 96 while(1) 97 { 98 n = recvfrom(sockfd,&msg,sizeof(msg),0,(struct sockaddr *)&peer_addr,&addrlen); 99 if(n < 0){ 100 perror("Fail to recvfrom"); 101 exit(EXIT_FAILURE); 102 } 103 104 printf("--------------------------------------------\n"); 105 printf("Ip : %s\n",inet_ntoa(peer_addr.sin_addr)); 106 printf("Port : %d\n",htons(peer_addr.sin_port)); 107 printf("Recv %d bytes : %s\n",n,msg.msg_buf); 108 printf("--------------------------------------------\n"); 109 110 if(msg.msg_type == SYSTEM_QUIT){ 111 exit(EXIT_SUCCESS); 112 } 113 } 114 115 return ; 116 } 117 118 //./udp_client server_ip server_port client_name 119 int main(int argc, const char *argv[]) 120 { 121 int sockfd; 122 int ret; 123 pthread_t tid; 124 125 if(argc < 4){ 126 fprintf(stderr,"Usage : %s <server_ip> <server_port> <client_name>\n",argv[0]); 127 return -1; 128 } 129 130 131 sockfd = init_udp_client_socket(NULL,NULL); 132 //sockfd = init_udp_client_socket("192.168.0.137","9999"); 133 134 //create a thread for udp socket to recv message 135 ret = pthread_create(&tid,NULL,thread_recv_udp_message,&sockfd); 136 if(ret != 0){ 137 fprintf(stderr,"Fail to pthread_create : %s\n",strerror(ret)); 138 exit(EXIT_FAILURE); 139 } 140 141 send_udp_message(sockfd,argv[1],argv[2],argv[3]); 142 143 return 0; 144 }
标签:
原文地址:http://www.cnblogs.com/yuanxuya/p/5038830.html