赞
踩
1. TCP和UDP的区别
TCP(Transmission Control Protocol,传输控制协议)
UDP(User Datagram Protocol,用户数据报协议)
1.1 连接方式
1.2 可靠性
1.3 速度与效率
1.4 数据包处理
1.5 应用场景
1.6 资源消耗与复杂性
2. TCP接口函数
2.1 socket
socket(AF_INET, SOCK_STREAM, 0);
2.2 connect
int connect(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:
向接收端发送三次握手链接请求
参数:
sockfd:文件描述符
addr:接收方地址空间首地址
addrlen:接收方地址的大小
返回值:
成功返回0
失败返回-1
2.3 send (发的太块会阻塞)
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:
发送数据
参数:
sockfd:文件描述符
buf:存放数据空间首地址
len:发送数据长度
flags:属性 默认为0
返回值:
成功返回发送字节数
失败返回-1
2.4 recv
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:
接收数据
参数:
sockfd:文件描述符
buf:存放数据空间首地址
len:最多接收数据大小
flags:属性 默认为0
返回值:
成功返回实际接收字节数
失败返回-1
对方关闭套接字返回0
2.5 listen
int listen(int sockfd, int backlog);
功能:
监听链接请求
参数:
sockfd:文件描述符
backlog:允许最多等待链接的个数
返回值:
成功返回0
失败返回-1
2.6 accept(返回通信套接字)
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:
处理等待队列中第一个链接
参数:
sockfd:文件描述符
addr:存放链接对方地址信息空间首地址
addrlen:想要接收地址大小变量空间首地址
返回值:
成功返回与发送端建立的新文件描述符(通信套接字)
失败返回-1
2.7 inet_addr
in_addr_t inet_addr(const char *cp);
功能:
将字符串IP地址转换为二进制IP地址
参数:
cp:字符串IP地址空间首地址
返回值:
成功返回二进制IP地址
2.8 htons
uint16_t htons(uint16_t hostshort);
功能:
将本地字节序(小端)转换为网络字节序(大端)
参数:
hostshort:本地端口号
返回值:
返回网络字节序端口号
uint16_t ntohs(uint16_t netshort);
功能:
将网络字节序(大端)转换为本地字节序(小端)
2.9 bind
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
功能:
将套接字与IP地址端口绑定在一起
参数:
sockfd:文件描述符
addr:结构体空间首地址
addrlen:信息的长度
返回值:
成功返回0
失败返回-1
2.10 示例程序
(1)TCP单向通信
1. 头文件
- #ifndef _HEAD_H_
- #define _HEAD_H_
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/types.h> /* See NOTES */
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <arpa/inet.h>
- #include <time.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <pthread.h>
-
- #endif
2. makefile
- all:send recv
-
- send:send.c
- gcc $^ -o $@
- recv:recv.c
- gcc $^ -o $@
3. recv.c
- #include "head.h"
-
- int main(int argc, char const *argv[])
- {
- int confd = 0;
- int listfd = 0;
- int ret_connect = 0;
- int ret_bind = 0;
- int ret_listen = 0;
- struct sockaddr_in recvaddr;
- struct sockaddr_in sendaddr;
- socklen_t addrlen = sizeof(sendaddr);
- ssize_t ret_send = 0;
- ssize_t ret_recv = 0;
-
- listfd = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == listfd)
- {
- perror("socket error!\n");
- return -1;
- }
-
- bzero(&recvaddr,sizeof(recvaddr));
- bzero(&sendaddr,sizeof(sendaddr));
-
- recvaddr.sin_family = AF_INET;
- recvaddr.sin_port = htons(50000);
- recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");
-
- ret_bind = bind(listfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
- if (-1 == ret_bind)
- {
- perror("bind error!\n");
- return -1;
- }
-
- ret_listen = listen(listfd, 3);
- if (-1 == ret_listen)
- {
- perror("listen error!\n");
- return -1;
- }
-
- confd = accept(listfd, (struct sockaddr *)&sendaddr, &addrlen);
- if (-1 == confd)
- {
- perror("accept error!\n");
- return -1;
- }
-
- while (1)
- {
- char buf[256] = {0};
-
- ret_recv = recv(confd, buf, sizeof(buf), 0);
- if (ret_recv <= 0)
- {
- break;
- }
-
- time_t tm;
- time(&tm);
- sprintf(buf, "%s %s", buf, ctime(&tm));
-
- ret_send = send(confd, buf, strlen(buf), 0);
- if (-1 == ret_send)
- {
- perror("send error!\n");
- return -1;
- }
- }
-
- close(confd);
- close(listfd);
-
- return 0;
- }
4. send.c
- #include "head.h"
-
- int main(int argc, char const *argv[])
- {
- int confd = 0;
- int ret_connect = 0;
- struct sockaddr_in recvaddr;
- socklen_t addrlen = 0;
- ssize_t ret_send = 0;
- ssize_t ret_recv = 0;
-
- confd = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == confd)
- {
- perror("socket error!\n");
- return -1;
- }
-
- bzero(&recvaddr, sizeof(recvaddr));
-
- recvaddr.sin_family = AF_INET;
- recvaddr.sin_port = htons(50000);
- recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");
-
- ret_connect = connect(confd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
- if (-1 == ret_connect)
- {
- perror("connect error!\n");
- return -1;
- }
-
- while (1)
- {
- char buf[256] = {"supercarrydoinb"};
- ret_send = send(confd, buf, strlen(buf), 0);
- if (-1 == ret_connect)
- {
- perror("send error!\n");
- return -1;
- }
- ret_recv = recv(confd, buf, sizeof(buf), 0);
- if (ret_recv <= 0)
- {
- break;
- }
-
- printf("%s", buf);
- sleep(1);
- }
-
- close(confd);
-
- return 0;
- }
(2) TCP实现多线程双机聊天(chat)——注意:!!线程编译gcc要加后缀 -lpthread
1. 头文件
- #ifndef _HEAD_H_
- #define _HEAD_H_
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/types.h> /* See NOTES */
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <arpa/inet.h>
- #include <time.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <pthread.h>
-
- #endif
2. makefile
- all:send recv
-
- send:send.c
- gcc $^ -o $@ -lpthread
- recv:recv.c
- gcc $^ -o $@ -lpthread
3. send.c
- #include "head.h"
-
- struct sockaddr_in sendaddr;
- struct sockaddr_in recvaddr;
-
- void *th1(void *arg)
- {
- int confd = *(int *)arg;
- ssize_t ret_recv = 0;
- while (1)
- {
- char buf[256] = {0};
- ret_recv = recv(confd, buf, sizeof(buf), 0);
- if (-1 == ret_recv)
- {
- perror("recv error!\n");
- }
- printf("from recv: %s\n", buf);
- }
- }
-
- void *th2(void *arg)
- {
- int confd = *(int *)arg;
- ssize_t ret_send = 0;
- while (1)
- {
- printf("to recv:");
- char buf[256] = {0};
- fgets(buf, sizeof(buf), stdin);
- buf[strlen(buf)-1] = '\0';
- ret_send= send(confd, buf, strlen(buf), 0);
- if (-1 == ret_send)
- {
- perror("send error!\n");
- }
- }
- }
-
- int main(int argc, char const *argv[])
- {
- int confd = 0;
- int ret_connect = 0;
- socklen_t addrlen = sizeof(sendaddr);
- ssize_t ret_recv = 0;
- ssize_t ret_send = 0;
- pthread_t tid1;
- pthread_t tid2;
- char buf[256] = {0};
-
- confd = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == confd)
- {
- perror("socket error!\n");
- return -1;
- }
-
- bzero(&recvaddr, sizeof(recvaddr));
- bzero(&sendaddr, sizeof(sendaddr));
-
- recvaddr.sin_family = AF_INET;
- recvaddr.sin_port = htons(50000);
- recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");
-
- ret_connect = connect(confd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
- if (-1 == ret_connect)
- {
- perror("connect error!\n");
- return -1;
- }
-
- #if 0
- ret_recv = recv(confd, buf, sizeof(buf), 0);
- if (-1 == ret_recv)
- {
- perror("recv error!\n");
- return -1;
- }
- #endif
-
- pthread_create(&tid1, NULL, th1, &confd);
- pthread_create(&tid2, NULL, th2, &confd);
-
- pthread_join(tid1, NULL);
- pthread_join(tid1, NULL);
-
- return 0;
- }
4. recv.c
- #include "head.h"
-
- struct sockaddr_in sendaddr;
- struct sockaddr_in recvaddr;
-
- void *th1(void *arg)
- {
- int confd = *(int *)arg;
- ssize_t ret_recv = 0;
- while (1)
- {
- char buf[256] = {0};
- ret_recv = recv(confd, buf, sizeof(buf), 0);
- if (-1 == ret_recv)
- {
- perror("recv error!\n");
- }
- printf("from send: %s\n", buf);
- }
- }
-
- void *th2(void *arg)
- {
- int confd = *(int *)arg;
- ssize_t ret_send = 0;
- while (1)
- {
- printf("to send:");
- char buf[256] = {0};
- fgets(buf, sizeof(buf), stdin);
- buf[strlen(buf)-1] = '\0';
- ret_send = send(confd, buf, strlen(buf), 0);
- if (-1 == ret_send)
- {
- perror("send error!\n");
- }
- }
- }
-
- int main(int argc, char const *argv[])
- {
- int listfd = 0;
- int confd = 0;
- int ret_bind = 0;
- int ret_listen = 0;
- socklen_t addrlen = sizeof(sendaddr);
- ssize_t ret_recv = 0;
- ssize_t ret_send = 0;
- pthread_t tid1;
- pthread_t tid2;
- char buf[256] = {0};
-
- listfd = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == listfd)
- {
- perror("socket error!\n");
- return -1;
- }
-
- bzero(&recvaddr, sizeof(recvaddr));
- bzero(&sendaddr, sizeof(sendaddr));
-
- recvaddr.sin_family = AF_INET;
- recvaddr.sin_port = htons(50000);
- recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");
-
- ret_bind = bind(listfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
- if (-1 == ret_bind)
- {
- perror("bind error!\n");
- return -1;
- }
-
- ret_listen = listen(listfd, 3);
- if (-1 == ret_listen)
- {
- perror("listen error!\n");
- return -1;
- }
-
- confd = accept(listfd, (struct sockaddr *)&sendaddr, &addrlen);
- if (-1 == confd)
- {
- perror("accept error!\n");
- return -1;
- }
-
- #if 0
- ret_recv = recv(confd, buf, sizeof(buf), 0);
- if (-1 == ret_recv)
- {
- perror("recv error!\n");
- return -1;
- }
- #endif
-
- pthread_create(&tid1, NULL, th1, &confd);
- pthread_create(&tid2, NULL, th2, &confd);
-
- pthread_join(tid1, NULL);
- pthread_join(tid1, NULL);
-
- return 0;
- }
(3) TCP实现文件的传输(结构体)
1. 头文件
- #ifndef _HEAD_H_
- #define _HEAD_H_
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/types.h> /* See NOTES */
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <arpa/inet.h>
- #include <time.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <pthread.h>
-
- #endif
2. makefile
- all:send recv
-
- send:send.c
- gcc $^ -o $@ -lpthread
- recv:recv.c
- gcc $^ -o $@ -lpthread
3. send.c
- #include "head.h"
-
- typedef struct
- {
- char buf[1024];
- char filename[32];
- int rd_ret;
- int total;
- }MSG;
-
- int main(int argc, char const *argv[])
- {
- int ret_connect = 0;
- int ret_stat = 0;
- int confd = 0;
- int openfd = 0;
- ssize_t ret_recv = 0;
- ssize_t ret_send = 0;
- struct sockaddr_in recvaddr;
- MSG msg;
- struct stat st;
-
- confd = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == confd)
- {
- perror("socket error!\n");
- return -1;
- }
-
- bzero(&recvaddr, sizeof(recvaddr));
- bzero(&msg, sizeof(msg));
-
- recvaddr.sin_family = AF_INET;
- recvaddr.sin_port = htons(50000);
- recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");
-
- ret_connect = connect(confd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
- if (-1 == ret_connect)
- {
- perror("connetc error!\n");
- return -1;
- }
-
- openfd = open("./1.png", O_RDONLY);
- if (-1 == openfd)
- {
- perror("open error!\n");
- return -1;
- }
-
- strcpy(msg.filename, "2.png");
-
- ret_stat = stat("./1.png", &st);
- if (-1 == ret_stat)
- {
- perror("stat error!\n");
- return -1;
- }
- msg.total = st.st_size;
-
- while (1)
- {
- bzero(msg.buf, sizeof(msg.buf));
-
- msg.rd_ret = read(openfd, msg.buf, sizeof(msg.buf));
- send(confd, &msg, sizeof(msg), 0);
- if (msg.rd_ret <= 0)
- {
- break;
- }
- char buf[256] = {0};
- ret_recv = recv(confd, buf, sizeof(buf), 0);
- if (ret_recv <= 0)
- {
- break;
- }
- usleep(1000 * 200);
- }
-
- close(confd);
- close(openfd);
-
- return 0;
- }
4. recv.c
- #include "head.h"
-
- typedef struct
- {
- char buf[1024];
- char filename[32];
- int rd_ret;
- int total;
- }MSG;
-
- int main(int argc, char const *argv[])
- {
- int listfd = 0;
- int ret_bind = 0;
- int ret_listen = 0;
- int confd = 0;
- ssize_t ret_recv = 0;
- ssize_t ret_send = 0;
- struct sockaddr_in recvaddr;
- struct sockaddr_in sendaddr;
- socklen_t addrlen = sizeof(sendaddr);
- MSG msg;
-
- listfd = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == listfd)
- {
- perror("socket error!\n");
- return -1;
- }
-
- bzero(&recvaddr, sizeof(recvaddr));
- bzero(&sendaddr, sizeof(sendaddr));
- bzero(&msg, sizeof(msg));
-
- recvaddr.sin_family = AF_INET;
- recvaddr.sin_port = htons(50000);
- recvaddr.sin_addr.s_addr = inet_addr("192.168.0.109");
-
- ret_bind = bind(listfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
- if (-1 == ret_bind)
- {
- perror("bind error!\n");
- return -1;
- }
-
-
- ret_listen = listen(listfd, 3);
- if (-1 == ret_listen)
- {
- perror("listen error!\n");
- return -1;
- }
-
- confd = accept(listfd, (struct sockaddr *)&sendaddr, &addrlen);
- if (-1 == confd)
- {
- perror("accept error!\n");
- return -1;
- }
-
- int openfd = 0;
- int flag = 0;
- int total = 0;
- int current_size = 0;
- while (1)
- {
- ret_recv = recv(confd, &msg, sizeof(msg), 0);
- if (ret_recv <= 0)
- {
- break;
- }
-
- if (0 == msg.rd_ret)
- {
- printf("file upload end\n");
- return -1;
- }
-
- if (0 == flag)//拿到文件总大小
- {
- openfd = open(msg.filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
- if (-1 == openfd)
- {
- perror("open error!\n");
- return -1;
- }
-
- flag = 1;
- total = msg.total;
- }
-
- write(openfd, msg.buf, msg.rd_ret);
- current_size += msg.rd_ret;
- printf("%d / %d\n", current_size, total);
- char buf[256] = "go on";
- send(confd, buf, strlen(buf), 0);
- }
-
- close(confd);
- close(openfd);
- close(listfd);
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。