代码示例_网络编程_select_内核链表
select_list
1.头文件
1 #pragma once 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <sys/types.h> 6 #include <sys/select.h> 7 #include <sys/time.h> 8 #include <sys/socket.h> 9 #include <strings.h> 10 #include <string.h> 11 #include <arpa/inet.h> 12 #include "list.h" 13 14 #define IP "192.168.2.150" 15 #define PORT 9999 16 #define SIZE 128 17 18 structcli_info19 {20 structlist_head list;21 intcli_fd;22 };
2.client_delect.c
1 #include "net.h" 2 3 int main(void)4 {5 //1.创建套接字 6 int fd = socket(AF_INET,SOCK_STREAM,0);7 if(fd<0){8 perror("socket failed");9 exit(1);10 }11 12 13 //2.初始服务器地址 14 structsockaddr_in cli;15 cli.sin_family =AF_INET;16 cli.sin_port =htons(PORT);17 cli.sin_addr.s_addr=inet_addr(IP);18 19 20 //3.发送连接请求 21 if( connect(fd,(struct sockaddr*)&cli,sizeof(cli))<0){22 perror("connect failed");23 exit(1);24 }25 26 27 //4.写 28 charbuf[SIZE];29 while(1){30 bzero(buf,SIZE);31 printf("please input:\t");32 fgets(buf,SIZE,stdin);33 write(fd,buf,strlen(buf));34 if(!strncmp(buf,"quit",4))35 break;36 }37 38 39 //5.关闭 40 close(fd);41 42 43 return 0;44 }
3.server_select.c
1 #include "net.h" 2 3 int main(void)4 {5 charbuf[SIZE];6 int newfd = -1;7 8 9 //*****定义初始头结点 10 structcli_info head;11 INIT_LIST_HEAD(&head.list);12 13 14 //1.创建套接字 15 int fd = socket(AF_INET,SOCK_STREAM,0);16 if(fd<0){17 perror("socket failed");18 exit(1);19 }20 21 22 //2.初始本地地址 23 structsockaddr_in ser;24 bzero(&ser,sizeof(ser));25 ser.sin_family =AF_INET;26 ser.sin_port =htons(PORT);27 ser.sin_addr.s_addr=htonl(INADDR_ANY);28 29 30 //3.绑定 31 if( bind(fd,(struct sockaddr*)&ser,sizeof(ser))<0){32 perror("bind failed");33 exit(1);34 }35 36 37 //4.监听 38 if( listen(fd,5)<0){39 perror("listen failed");40 exit(1);41 }42 43 int len = sizeof(ser);44 int maxfd = -1;45 46 //5.多路复用 47 fd_set read_fds; //定义读集合 48 FD_ZERO(&read_fds); //清空读集合 49 maxfd = fd; //最大描述符50 51 52 //***** 53 struct cli_info *cur=NULL;54 struct list_head *ptr,*q;55 56 57 //6.加入监听处理 读集合 58 while(1){59 FD_SET(0,&read_fds); //将标准输入加入读集合 60 FD_SET(fd,&read_fds); //将fd加入读集合 61 maxfd = fd; //表示最大读集合 62 63 #if 0 64 if(maxfd <newfd){65 FD_SET(newfd,&read_fds);66 maxfd=newfd;67 }68 #endif 69 70 //*****将文件描述符加入到读集合 71 list_for_each(ptr,&head.list){72 cur = list_entry(ptr,structcli_info,list);73 FD_SET(cur->cli_fd,&read_fds);74 if(maxfd<cur->cli_fd)75 maxfd = cur->cli_fd;76 }77 78 79 int ret = select(maxfd+1,&read_fds,NULL,NULL,NULL);80 if(ret<0){81 perror("select failed");82 exit(1);83 }84 else if(ret==0){85 perror("time out");86 exit(1);87 }88 else{89 //6.1 判断输入端是否有相应 90 if(FD_ISSET(0,&read_fds)){91 bzero(buf,SIZE);92 fgets(buf,SIZE,stdin);93 printf("shell :%s",buf);94 }95 96 97 //6.2 判断客户端是否有相应 98 if(FD_ISSET(fd,&read_fds)){99 //*****给新节点申请空间 100 struct cli_info *temp=(struct cli_info*)malloc(sizeof(structcli_info));101 if(temp==NULL){102 perror("malloc failed");103 exit(1);104 }105 //接收 106 newfd=accept(fd,(struct sockaddr*)&ser,&len);107 if(newfd<0){108 perror("accept failed");109 exit(1);110 }111 printf("client connect succsee : ip=%s port=%d 用户上线啦 ^.^ ...\n",inet_ntoa(ser.sin_addr),ntohs(ser.sin_port));112 //*****将连接的新客户文件描述符加入到新节点 113 temp->cli_fd=newfd;114 //*****把新节点插入到链表 115 list_add(&temp->list,&head.list);116 }117 118 119 //6.3 判断客户端是否有数据 120 list_for_each_safe(ptr,q,&head.list){121 cur = list_entry(ptr,structcli_info,list);122 if(FD_ISSET(cur->cli_fd,&read_fds)){123 bzero(buf,SIZE);124 int val = read(cur->cli_fd,buf,SIZE);125 if(val<0){126 perror("read failed");127 exit(1);128 }129 else if(val==0){130 FD_CLR(cur->cli_fd,&read_fds);131 list_del(&cur->list);132 close(cur->cli_fd);133 free(cur);134 cur->cli_fd = -1;135 }136 else{137 printf("client info :\nip=%s port=%d\ndata=%s\n",inet_ntoa(ser.sin_addr),ntohs(ser.sin_port),buf);138 if(!strncmp(buf,"quit",4))139 printf("client info :\nip=%s port=%d 用户下线啦 ^.^ ...\n",inet_ntoa(ser.sin_addr),ntohs(ser.sin_port));140 141 }142 }143 }144 }145 }146 147 148 return 0;149 }
4.list.h
1 #ifndef _LINUX_LIST_H2 #define _LINUX_LIST_H 3 4 /* 5 * Simple doubly linked list implementation.6 *7 * Some of the internal functions ("__xxx") are useful when8 * manipulating whole lists rather than single entries, as9 * sometimes we already know the next/prev entries and we can10 * generate better code by using them directly rather than11 * using the generic single-entry routines.12 */ 13 14 structlist_head{15 struct list_head *next,*prev;16 };17 18 #define LIST_POISON1 ((void *) 0x00100100 + 0) 19 #define LIST_POISON2 ((void *) 0x00200200 + 0) 20 21 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 22 #define container_of(ptr, type, member) ({ \ 23 const typeof( ((type *)0)->member ) *__mptr =(ptr); \24 (type *)( (char *)__mptr -offsetof(type,member) );})25 #define LIST_HEAD_INIT(name) { &(name), &(name) } 26 27 #define LIST_HEAD(name) \ 28 struct list_head name =LIST_HEAD_INIT(name)29 30 static inline void INIT_LIST_HEAD(struct list_head *list)31 {32 list->next =list;33 list->prev =list;34 }35 36 /* 37 * Insert a new entry between two known consecutive entries.38 *39 * This is only for internal list manipulation where we know40 * the prev/next entries already!41 */ 42 #ifndef CONFIG_DEBUG_LIST43 static inline void __list_add(struct list_head *new,44 struct list_head *prev,45 struct list_head *next)46 {47 next->prev = new;48 new->next =next;49 new->prev =prev;50 prev->next = new;51 }52 #else 53 extern void __list_add(struct list_head *new,54 struct list_head *prev,55 struct list_head *next);56 #endif 57 58 /**59 * list_add - add a new entry60 * @new: new entry to be added61 * @head: list head to add it after62 *63 * Insert a new entry after the specified head.64 * This is good for implementing stacks.65 */ 66 static inline void list_add(struct list_head *new, struct list_head *head)67 {68 __list_add(new, head, head->next);69 }70 71 72 /**73 * list_add_tail - add a new entry74 * @new: new entry to be added75 * @head: list head to add it before76 *77 * Insert a new entry before the specified head.78 * This is useful for implementing queues.79 */ 80 static inline void list_add_tail(struct list_head *new, struct list_head *head)81 {82 __list_add(new, head->prev, head);83 }84 85 /* 86 * Delete a list entry by making the prev/next entries87 * point to each other.88 *89 * This is only for internal list manipulation where we know90 * the prev/next entries already!91 */ 92 static inline void __list_del(struct list_head * prev, struct list_head *next)93 {94 next->prev =prev;95 prev->next =next;96 }97 98 /**99 * list_del - deletes entry from list.100 * @entry: the element to delete from the list.101 * Note: list_empty() on entry does not return true after this, the entry is102 * in an undefined state.103 */ 104 #ifndef CONFIG_DEBUG_LIST105 static inline void __list_del_entry(struct list_head *entry)106 {107 __list_del(entry->prev, entry->next);108 }109 110 static inline void list_del(struct list_head *entry)111 {112 __list_del(entry->prev, entry->next);113 entry->next =LIST_POISON1;114 entry->prev =LIST_POISON2;115 }116 #else 117 extern void __list_del_entry(struct list_head *entry);118 extern void list_del(struct list_head *entry);119 #endif 120 121 /**122 * list_replace - replace old entry by new one123 * @old : the element to be replaced124 * @new : the new element to insert125 *126 * If @old was empty, it will be overwritten.127 */ 128 static inline void list_replace(struct list_head *old,129 struct list_head *new)130 {131 new->next = old->next;132 new->next->prev = new;133 new->prev = old->prev;134 new->prev->next = new;135 }136 137 static inline void list_replace_init(struct list_head *old,138 struct list_head *new)139 {140 list_replace(old, new);141 INIT_LIST_HEAD(old);142 }143 144 /**145 * list_del_init - deletes entry from list and reinitialize it.146 * @entry: the element to delete from the list.147 */ 148 static inline void list_del_init(struct list_head *entry)149 {150 __list_del_entry(entry);151 INIT_LIST_HEAD(entry);152 }153 154 /**155 * list_move - delete from one list and add as another's head156 * @list: the entry to move157 * @head: the head that will precede our entry158 */ 159 static inline void list_move(struct list_head *list, struct list_head *head)160 {161 __list_del_entry(list);162 list_add(list, head);163 }164 165 /**166 * list_move_tail - delete from one list and add as another's tail167 * @list: the entry to move168 * @head: the head that will follow our entry169 */ 170 static inline void list_move_tail(struct list_head *list,171 struct list_head *head)172 {173 __list_del_entry(list);174 list_add_tail(list, head);175 }176 177 /**178 * list_is_last - tests whether @list is the last entry in list @head179 * @list: the entry to test180 * @head: the head of the list181 */ 182 static inline int list_is_last(const struct list_head *list,183 const struct list_head *head)184 {185 return list->next ==head;186 }187 188 /**189 * list_empty - tests whether a list is empty190 * @head: the list to test.191 */ 192 static inline int list_empty(const struct list_head *head)193 {194 return head->next ==head;195 }196 197 /**198 * list_empty_careful - tests whether a list is empty and not being modified199 * @head: the list to test200 *201 * Description:202 * tests whether a list is empty _and_ checks that no other CPU might be203 * in the process of modifying either member (next or prev)204 *205 * NOTE: using list_empty_careful() without synchronization206 * can only be safe if the only activity that can happen207 * to the list entry is list_del_init(). Eg. it cannot be used208 * if another CPU could re-list_add() it.209 */ 210 static inline int list_empty_careful(const struct list_head *head)211 {212 struct list_head *next = head->next;213 return (next == head) && (next == head->prev);214 }215 216 /**217 * list_rotate_left - rotate the list to the left218 * @head: the head of the list219 */ 220 static inline void list_rotate_left(struct list_head *head)221 {222 struct list_head *first;223 224 if (!list_empty(head)) {225 first = head->next;226 list_move_tail(first, head);227 }228 }229 230 /**231 * list_is_singular - tests whether a list has just one entry.232 * @head: the list to test.233 */ 234 static inline int list_is_singular(const struct list_head *head)235 {236 return !list_empty(head) && (head->next == head->prev);237 }238 239 static inline void __list_cut_position(struct list_head *list,240 struct list_head *head, struct list_head *entry)241 {242 struct list_head *new_first = entry->next;243 list->next = head->next;244 list->next->prev =list;245 list->prev =entry;246 entry->next =list;247 head->next =new_first;248 new_first->prev =head;249 }250 251 /**252 * list_cut_position - cut a list into two253 * @list: a new list to add all removed entries254 * @head: a list with entries255 * @entry: an entry within head, could be the head itself256 * and if so we won't cut the list257 *258 * This helper moves the initial part of @head, up to and259 * including @entry, from @head to @list. You should260 * pass on @entry an element you know is on @head. @list261 * should be an empty list or a list you do not care about262 * losing its data.263 *264 */ 265 static inline void list_cut_position(struct list_head *list,266 struct list_head *head, struct list_head *entry)267 {268 if(list_empty(head))269 return;270 if (list_is_singular(head) && 271 (head->next != entry && head !=entry))272 return;273 if (entry ==head)274 INIT_LIST_HEAD(list);275 else 276 __list_cut_position(list, head, entry);277 }278 279 static inline void __list_splice(const struct list_head *list,280 struct list_head *prev,281 struct list_head *next)282 {283 struct list_head *first = list->next;284 struct list_head *last = list->prev;285 286 first->prev =prev;287 prev->next =first;288 289 last->next =next;290 next->prev =last;291 }292 293 /**294 * list_splice - join two lists, this is designed for stacks295 * @list: the new list to add.296 * @head: the place to add it in the first list.297 */ 298 static inline void list_splice(const struct list_head *list,299 struct list_head *head)300 {301 if (!list_empty(list))302 __list_splice(list, head, head->next);303 }304 305 /**306 * list_splice_tail - join two lists, each list being a queue307 * @list: the new list to add.308 * @head: the place to add it in the first list.309 */ 310 static inline void list_splice_tail(struct list_head *list,311 struct list_head *head)312 {313 if (!list_empty(list))314 __list_splice(list, head->prev, head);315 }316 317 /**318 * list_splice_init - join two lists and reinitialise the emptied list.319 * @list: the new list to add.320 * @head: the place to add it in the first list.321 *322 * The list at @list is reinitialised323 */ 324 static inline void list_splice_init(struct list_head *list,325 struct list_head *head)326 {327 if (!list_empty(list)) {328 __list_splice(list, head, head->next);329 INIT_LIST_HEAD(list);330 }331 }332 333 /**334 * list_splice_tail_init - join two lists and reinitialise the emptied list335 * @list: the new list to add.336 * @head: the place to add it in the first list.337 *338 * Each of the lists is a queue.339 * The list at @list is reinitialised340 */ 341 static inline void list_splice_tail_init(struct list_head *list,342 struct list_head *head)343 {344 if (!list_empty(list)) {345 __list_splice(list, head->prev, head);346 INIT_LIST_HEAD(list);347 }348 }349 350 /**351 * list_entry - get the struct for this entry352 * @ptr: the &struct list_head pointer.353 * @type: the type of the struct this is embedded in.354 * @member: the name of the list_struct within the struct.355 */ 356 #define list_entry(ptr, type, member) \ 357 container_of(ptr, type, member)358 359 /**360 * list_first_entry - get the first element from a list361 * @ptr: the list head to take the element from.362 * @type: the type of the struct this is embedded in.363 * @member: the name of the list_struct within the struct.364 *365 * Note, that list is expected to be not empty.366 */ 367 #define list_first_entry(ptr, type, member) \ 368 list_entry((ptr)->next, type, member)369 370 /**371 * list_for_each - iterate over a list372 * @pos: the &struct list_head to use as a loop cursor.373 * @head: the head for your list.374 */ 375 #define list_for_each(pos, head) \ 376 for (pos = (head)->next; pos != (head); pos = pos->next)377 378 /**379 * __list_for_each - iterate over a list380 * @pos: the &struct list_head to use as a loop cursor.381 * @head: the head for your list.382 *383 * This variant doesn't differ from list_for_each() any more.384 * We don't do prefetching in either case.385 */ 386 #define __list_for_each(pos, head) \ 387 for (pos = (head)->next; pos != (head); pos = pos->next)388 389 /**390 * list_for_each_prev - iterate over a list backwards391 * @pos: the &struct list_head to use as a loop cursor.392 * @head: the head for your list.393 */ 394 #define list_for_each_prev(pos, head) \ 395 for (pos = (head)->prev; pos != (head); pos = pos->prev)396 397 /**398 * list_for_each_safe - iterate over a list safe against removal of list entry399 * @pos: the &struct list_head to use as a loop cursor.400 * @n: another &struct list_head to use as temporary storage401 * @head: the head for your list.402 */ 403 #define list_for_each_safe(pos, n, head) \ 404 for (pos = (head)->next, n = pos->next; pos !=(head); \405 pos = n, n = pos->next)406 407 /**408 * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry409 * @pos: the &struct list_head to use as a loop cursor.410 * @n: another &struct list_head to use as temporary storage411 * @head: the head for your list.412 */ 413 #define list_for_each_prev_safe(pos, n, head) \ 414 for (pos = (head)->prev, n = pos->prev; \415 pos !=(head); \416 pos = n, n = pos->prev)417 418 /**419 * list_for_each_entry - iterate over list of given type420 * @pos: the type * to use as a loop cursor.421 * @head: the head for your list.422 * @member: the name of the list_struct within the struct.423 */ 424 #define list_for_each_entry(pos, head, member) \ 425 for (pos = list_entry((head)->next, typeof(*pos), member); \426 &pos->member !=(head); \427 pos = list_entry(pos->member.next, typeof(*pos), member))428 429 /**430 * list_for_each_entry_reverse - iterate backwards over list of given type.431 * @pos: the type * to use as a loop cursor.432 * @head: the head for your list.433 * @member: the name of the list_struct within the struct.434 */ 435 #define list_for_each_entry_reverse(pos, head, member) \ 436 for (pos = list_entry((head)->prev, typeof(*pos), member); \437 &pos->member !=(head); \438 pos = list_entry(pos->member.prev, typeof(*pos), member))439 440 /**441 * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()442 * @pos: the type * to use as a start point443 * @head: the head of the list444 * @member: the name of the list_struct within the struct.445 *446 * Prepares a pos entry for use as a start point in list_for_each_entry_continue().447 */ 448 #define list_prepare_entry(pos, head, member) \ 449 ((pos) ? : list_entry(head, typeof(*pos), member))450 451 /**452 * list_for_each_entry_continue - continue iteration over list of given type453 * @pos: the type * to use as a loop cursor.454 * @head: the head for your list.455 * @member: the name of the list_struct within the struct.456 *457 * Continue to iterate over list of given type, continuing after458 * the current position.459 */ 460 #define list_for_each_entry_continue(pos, head, member) \ 461 for (pos = list_entry(pos->member.next, typeof(*pos), member); \462 &pos->member !=(head); \463 pos = list_entry(pos->member.next, typeof(*pos), member))464 465 /**466 * list_for_each_entry_continue_reverse - iterate backwards from the given point467 * @pos: the type * to use as a loop cursor.468 * @head: the head for your list.469 * @member: the name of the list_struct within the struct.470 *471 * Start to iterate over list of given type backwards, continuing after472 * the current position.473 */ 474 #define list_for_each_entry_continue_reverse(pos, head, member) \ 475 for (pos = list_entry(pos->member.prev, typeof(*pos), member); \476 &pos->member !=(head); \477 pos = list_entry(pos->member.prev, typeof(*pos), member))478 479 /**480 * list_for_each_entry_from - iterate over list of given type from the current point481 * @pos: the type * to use as a loop cursor.482 * @head: the head for your list.483 * @member: the name of the list_struct within the struct.484 *485 * Iterate over list of given type, continuing from current position.486 */ 487 #define list_for_each_entry_from(pos, head, member) \ 488 for (; &pos->member !=(head); \489 pos = list_entry(pos->member.next, typeof(*pos), member))490 491 /**492 * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry493 * @pos: the type * to use as a loop cursor.494 * @n: another type * to use as temporary storage495 * @head: the head for your list.496 * @member: the name of the list_struct within the struct.497 */ 498 #define list_for_each_entry_safe(pos, n, head, member) \ 499 for (pos = list_entry((head)->next, typeof(*pos), member), \500 n = list_entry(pos->member.next, typeof(*pos), member); \501 &pos->member !=(head); \502 pos = n, n = list_entry(n->member.next, typeof(*n), member))503 504 /**505 * list_for_each_entry_safe_continue - continue list iteration safe against removal506 * @pos: the type * to use as a loop cursor.507 * @n: another type * to use as temporary storage508 * @head: the head for your list.509 * @member: the name of the list_struct within the struct.510 *511 * Iterate over list of given type, continuing after current point,512 * safe against removal of list entry.513 */ 514 #define list_for_each_entry_safe_continue(pos, n, head, member) \ 515 for (pos = list_entry(pos->member.next, typeof(*pos), member), \516 n = list_entry(pos->member.next, typeof(*pos), member); \517 &pos->member !=(head); \518 pos = n, n = list_entry(n->member.next, typeof(*n), member))519 520 /**521 * list_for_each_entry_safe_from - iterate over list from current point safe against removal522 * @pos: the type * to use as a loop cursor.523 * @n: another type * to use as temporary storage524 * @head: the head for your list.525 * @member: the name of the list_struct within the struct.526 *527 * Iterate over list of given type from current point, safe against528 * removal of list entry.529 */ 530 #define list_for_each_entry_safe_from(pos, n, head, member) \ 531 for (n = list_entry(pos->member.next, typeof(*pos), member); \532 &pos->member !=(head); \533 pos = n, n = list_entry(n->member.next, typeof(*n), member))534 535 /**536 * list_for_each_entry_safe_reverse - iterate backwards over list safe against removal537 * @pos: the type * to use as a loop cursor.538 * @n: another type * to use as temporary storage539 * @head: the head for your list.540 * @member: the name of the list_struct within the struct.541 *542 * Iterate backwards over list of given type, safe against removal543 * of list entry.544 */ 545 #define list_for_each_entry_safe_reverse(pos, n, head, member) \ 546 for (pos = list_entry((head)->prev, typeof(*pos), member), \547 n = list_entry(pos->member.prev, typeof(*pos), member); \548 &pos->member !=(head); \549 pos = n, n = list_entry(n->member.prev, typeof(*n), member))550 551 /**552 * list_safe_reset_next - reset a stale list_for_each_entry_safe loop553 * @pos: the loop cursor used in the list_for_each_entry_safe loop554 * @n: temporary storage used in list_for_each_entry_safe555 * @member: the name of the list_struct within the struct.556 *557 * list_safe_reset_next is not safe to use in general if the list may be558 * modified concurrently (eg. the lock is dropped in the loop body). An559 * exception to this is if the cursor element (pos) is pinned in the list,560 * and list_safe_reset_next is called after re-taking the lock and before561 * completing the current iteration of the loop body.562 */ 563 #define list_safe_reset_next(pos, n, member) \ 564 n = list_entry(pos->member.next, typeof(*pos), member)565 566 /* 567 * Double linked lists with a single pointer list head.568 * Mostly useful for hash tables where the two pointer list head is569 * too wasteful.570 * You lose the ability to access the tail in O(1).571 */ 572 #endif
测试:
success !
转载于:https://www.cnblogs.com/panda-w/p/11068140.html
代码示例_网络编程_select_内核链表相关推荐
- 代码示例_网络编程_select
select_多路复用 1.头文件 1 #pragma once 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include ...
- BIO,Socket网络编程入门代码示例,NIO网络编程入门代码示例,AIO 网络编程
BIO,Socket网络编程入门代码示例 1.BIO服务器端程序 package cn.itcast.bio;import java.io.InputStream; import java.io.Ou ...
- linux 应用层编程之内核链表list的使用
linux内核提供了一个经典通用的双向循环链表list的实现,任何模块都可以借助该接口实现自己的内部循环链表.因为是通用的,可以直接移植到用户态中使用,下面介绍相关的接口与一个简单操作例子,包括链表的 ...
- 2022.02.09_Java学习总结_网络编程、正则表达式
1. 网络编程 1.1 概述 Java是 Internet 上的语言,它从语言级上提供了对网络应用程序的支持,程序员能够很容易开发常见的网络应用程序. Java提供的网络类库,可以实现无痛的网络连接, ...
- java爬虫代码示例_那些让你代码思维和能力有较大的提升Java源码
来源:www.cnblogs.com/jiagou/p/9270070.html 对于学习J2EE的框架有很大的帮助,代码里使用了各种设计模式.事件机制.Java8语法.代码量也很小,web服务使用N ...
- udp recvfrom阻塞吗_网络编程原理与UDP实现
本文作者:PsgQ 本文链接:https://www.cnblogs.com/PsgQ/p/14089310.html 如何发送数据包? Q:当应用程序产生数据的时候,需要去构造数据包并发送到网络上去 ...
- 第六周 Java语法总结_设计原则_工厂模式_单例模式_代理模式(静态代理_动态代理)_递归_IO流_网络编程(UDP_TCP)_反射_数据库
文章目录 20.设计原则 1.工厂模式 2.单例模式 1)饿汉式 2)懒汉式 3.Runtime类 4.代理模式 1)静态代理 2)动态代理 动态代理模板 21.递归 22.IO流 1.File 2. ...
- 5_异常_多线程_设计模式_IO流_网络编程_反射
JavaSE_第五周 异常 异常的概念 什么是异常 概念 概念:程序在运行过程中出现的特殊情况异常-----通过Jvm将异常的信息打印在控制台---告诉开发者(当前程序在某个环节出现了哪些问题!) 异 ...
- A031_web基础_网络编程_Socket_Http_Tomcat
目录 1.内容介绍 2.计算机网络 3.网络编程相关术语 3.1.IP地址 3.2.Port端口 3.3.URL统一资源定位符 3.4.TCP传输控制协议 3.5.UDP用户数据报协议 3.6.TCP ...
最新文章
- 06day 03cdbpdb也成为 多租户环境
- pad_sequences序列填充(转载)
- Python类与对象实验
- 集合竞价如何买入_世界上最稳健的抓涨停方法“10分钟集合竞价”选股诀窍,买入直接稳赚10个点,赚到笑...
- android 多媒体文件信息,Android 获取多媒体信息
- 亲身经历:一个00后的中专生是怎么在深圳拿到30K(Java后端开发)
- BOBSLEDDING(一道有趣的贪心题 nyoj309)
- Java 反射Reflection总结一
- 无所不在的嵌入式系统
- 应用内悬浮窗适配方案实战
- snakemake--我最喜欢的流程管理工具
- HSI、HSV、RGB、CMY、CMYK、HSL、HSB、Ycc、XYZ、Lab、YUV颜色模型
- MAC常用命令及快捷键
- 分享一款免费OPC UA服务器
- 股权模板:55套股权激励方案
- mysql账号认证_浅谈MySQL用户账号认证方式
- zynq 移植ubuntu_ROS ZYNQ移植
- SLAM基础问题总结(1)
- 12.20-12.21北大医药
- jq实现一个简易的选项卡