一、TCP/UDP对比
- TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前 不需 要建立连接
- TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付
- TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的
UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等) - 每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
- TCP首部开销20字节;UDP的首部开销小,只有8个字节
- TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道
二、socket编程步骤
(1)服务器
1、socket()创建套接字
2、bind()为套接字添加信息(IP地址和端口号)
3、listen()监听网络连接
4、accept()监听到有客户端接入,接受一个连接
5、read()write()数据交互
6、close()关闭套接字,断开连接
(2)客户端
1、socket()
2、connect()
3、write()
4、read()
5、close()
三、服务器代码编程
ps:通过 cd/usr/include 进入该目录,再grep “struct sockaddr_in {” * -nir 找到头文件(linux/in.h)加进去。再vi linux/in.h 可以查看到该结构体。
#include <stdio.h>
2 #include <sys/types.h> /* See NOTES */
3 #include <sys/socket.h>
4 //#include <linux/in.h>
5 #include <arpa/inet.h>
6 #include <netinet/in.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 int main(int argv,char **argc) //为了传入端口号 **argc
11 {
12 //1.socket
13 //int socket(int domain, int type, int protocol);
14
15 int s_fd;
16 int c_fd;
17 int n_read;
18
19 int mark=0;
20
21 struct sockaddr_in s_addr; //bind时第二个参数需要结构体
22 struct sockaddr_in c_addr;
23
24 if(argv != 3){ //提示信息参数不为三时出错
25 printf("parm is error");
26 exit(-1);
27
28 }
29 char readBuf[128]; //因为要写入操作需要开辟空间
30 // char *msg = "i get Your message";
31 char msg[128] = {0};
32 memset(&s_addr,0,sizeof(struct sockaddr_in)); //初始化
33 memset(&c_addr,0,sizeof(struct sockaddr_in));
34
35 s_fd = socket(AF_INET,SOCK_STREAM,0); //AF_INET,SOCK_STREAM 为tcp设置
36 if(s_fd == -1){
37 perror("socket");
38 exit(-1);
39 }
40
//2.bind
42 //int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
43
44
45 s_addr.sin_family = AF_INET;
46 s_addr.sin_port = htons(atoi(argc[2])); //用户一般用在5000-9000之间
47 inet_aton(argc[1],&s_addr.sin_addr);
48 bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
49
50 //3.listen
51
52 listen(s_fd,10);
53 //4.accept
54 // int accept4(int sockfd, struct sockaddr *addr,socklen_t *addrlen, int flags);
55 while(1){ //为了能够不断接收客户端数据
56
57 int clen = sizeof(struct sockaddr_in);
58 c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);
59 if(c_fd == -1){
60 perror("accept");
61 }
62 printf("get connect %s\n",inet_ntoa(c_addr.sin_addr));
63
64 mark++;
65 //5.read
66 if(fork() == 0){ //创建子进程
67
68 if(fork() == 0){
69 while(1){ //保持一直写入操作
70 //6.write
71 sprintf(msg,"welcome no.%dclient",mark);
72 write(c_fd,msg,strlen(msg));
73 sleep(3);
74 }
75 }
76 while(1){
77 memset(readBuf,0,sizeof(readBuf)); //初始化设置
78 n_read = read(c_fd,readBuf,128);
79 if(n_read == -1){
80 perror("read");
81 }else{
82 printf("get message:%s\n",readBuf);
83 }
84 }
85
86 }
87 }
88 return 0;
89 }
(2)客户端代码编程
#include <stdio.h>
2 #include <sys/types.h> /* See NOTES */
3 #include <sys/socket.h>
4 //#include <linux/in.h>
5 #include <arpa/inet.h>
6 #include <netinet/in.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <unistd.h>
10 int main(int argv,char **argc)
11 {
12 //1.socket
13 //int socket(int domain, int type, int protocol);
14
15 int c_fd;
16 int n_read;
17
18 struct sockaddr_in c_addr;
19 if(argv != 3){
20 printf("parm is error");
21 exit(-1);
22
23 }
24
25 char readBuf[128];
26 // char *msg = "message from client";
27 char msg[128] = {0};
28 memset(&c_addr,0,sizeof(struct sockaddr_in));
29
30 c_fd = socket(AF_INET,SOCK_STREAM,0);
31 if(c_fd == -1){
32 perror("socket");
33 exit(-1);
34 }
35
36 //2.connect
37 //int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
38
39 c_addr.sin_family = AF_INET;
40 c_addr.sin_port = htons(atoi(argc[2])); //用户一般用在5000-9000之间
41 inet_aton(argc[1],&c_addr.sin_addr);
42 if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in)) == -1){
43
44 perror("connect");
45 exit(-1);
46 }
47
48 while(1){
49
50 if(fork() == 0){
51 while(1){ //不断写入
52 //3.write
53 memset(msg,0,sizeof(msg));
54 printf("input msg ");
55 gets(msg);
56
57 write(c_fd,msg,strlen(msg));
58 }
59 }
60 while(1){ //不断获取
61 //4.read
62 memset(readBuf,0,sizeof(readBuf)); //每次初始化数据不会重叠
63 n_read = read(c_fd,readBuf,128);
64 if(n_read == -1){
65 perror("read");
66 }else{
67 printf("get message from sever:%s\n",readBuf);
68 }
69 }
70 }
71 return 0;
72 }