在网络传输协议中,TCP协议提供的是一种可靠的,复杂的,面向连接的数据流(SOCK_STREAM)传输服务,它通过三段式握手过程建立连接。TCP有一种“重传确认”机制,即接收端收到数据后要发出一个肯定确认的信号,发送端如果收到接收端肯定确认的信号,就会继续发送其他的数据,如果没有,它就会重新发送。
相对而言,UDP协议则是一种无连接的,不可靠的数据报(SOCK_DGRAM)传输服务。使用UDP套接口不用建立连接,服务端在调用socket()生成一个套接字并调用bind()绑定端口后就可以进行通信(recvfrom函数和sendto函数)了;客户端在用socket()生成一个套接字后就可以向服务端地址发送和接收数据了。
此处需要特别注意:TCP使用的是流套接字(SOCK_STREAM),UDP使用的是数据报套接字(SOCK_DGRAM)
关于socket的配置:
1、创建sokcet套接字
2、为创建的socket绑定地址与端口,指定传输的协议,一般采用AF_INET,数据的传输格式一般为(SOCK_STREAM、SOCK_DGRAM)
3、打开文件标识符,并开始发送数据
udp客户端CODE:
- <pre name="code" class="html">#include <unistd.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
-
- void client(int sock){
-
- struct sockaddr_in servaddr;
- memset(&servaddr, 0, sizeof(servaddr));
-
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(5188);
- servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
-
-
- int ret;
- char sendbuf[1024] = {0};
- char recvbuf[1024] = {0};
-
- while(fgets(sendbuf, sizeof(sendbuf), stdin) != NULL){
- sendto(sock, sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
-
- ret = recvfrom(sock, recvbuf, sizeof(recvbuf), 0, NULL, NULL);
- if(ret == -1){
- perror("recvfrom");
- exit(EXIT_FAILURE);
- }
-
-
-
-
- memset(sendbuf, 0, sizeof(sendbuf));
- memset(recvbuf, 0, sizeof(recvbuf));
- }
-
- close(sock);
- }
-
- int main(void){
- int sock;
-
- if((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0){
- perror("socket");
- exit(EXIT_FAILURE);
- }
- client(sock);
- return 0;
- }
UDP服务端CODE:
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <string.h>
-
- void server(int sock){
-
- char recvbuf[1024] = {0};
-
- struct sockaddr_in peeraddr;
- socklen_t peerlen;
- int n;
- while(1){
-
- peerlen = sizeof(peeraddr);
-
- memset(recvbuf, 0, sizeof(recvbuf));
-
- n = recvfrom(sock, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *)&peeraddr, &peerlen);
-
- if(n == -1){
- perror("recvfrom");
- exit(EXIT_FAILURE);
- }else if(n > 0){
-
- fputs(recvbuf, stdout);
-
- sendto(sock, recvbuf, n, 0, (struct sockaddr *)&peeraddr, peerlen);
- }
- }
-
- close(sock);
- }
-
- int main(void){
- int sock;
-
- if((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0){
- perror("socket error");
- exit(EXIT_FAILURE);
- }
-
- struct sockaddr_in servaddr;
- memset(&servaddr, 0, sizeof(servaddr));
-
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(5188);
- servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
-
-
- if(bind(sock, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0){
- perror("bind error");
- exit(EXIT_FAILURE);
- }
- server(sock);
- return 0;
- }