阅读量:3
1.1UDP服务器的搭建
{ li.c #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h> #define PORT 8888 #define IP "192.168.124.34" #define ERR_MSG(msg) {fprintf(stderr, "line:%d ", __LINE__);\ perror(msg);\ } int main(int argc, const char *argv[]) { //创建报式套接字 int sfd = socket(AF_INET, SOCK_DGRAM, 0); if(sfd < 0) { ERR_MSG("socket"); return -1; } printf("socket create success sfd=%d\n", sfd); //填充地址信息结构体给bind函数使用 //真实的地址信息结构体根据地址族指定 AF_INET: man 7 IP struct sockaddr_in sin; sin.sin_family = AF_INET; //必须填AF_INET; sin.sin_port = htons(PORT); //端口号的网络字节序,1024~49151 sin.sin_addr.s_addr = inet_addr(IP); //本机IP,ifconfig //绑定服务器自身的地址信息 if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("bind"); return -1; } printf("bind success\n"); struct sockaddr_in cin; //存储发送放的地址信息 socklen_t addrlen =sizeof(cin); char buf[128] = ""; ssize_t res = 0; while(1) { bzero(buf, sizeof(buf)); //接收数据 --->同时存储这个数据包是从哪里来的,即发送的地址 res = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &addrlen); if(res < 0) { ERR_MSG("recvfrom"); return -1; } printf("[%s:%d] : %s\n", \ inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf); //发送数据, 谁发给我,我发还给谁 strcat(buf, "*_*"); if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, sizeof(cin)) < 0) { ERR_MSG("sendto"); return -1; } printf("sendto success\n"); } //关闭套接字 close(sfd); return 0; }
1.2UDP客户端
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <unistd.h> #include <string.h> #define ERR_MSG(msg) do{\ fprintf(stderr, "__%d__ ", __LINE__);\ perror(msg);\ }while(0) #define SER_PORT 8888 //服务器绑定的端口号 #define SER_IP "192.168.124.34" //服务器绑定的IP int main(int argc, const char *argv[]) { //创建报式套接字 int cfd = socket(AF_INET, SOCK_DGRAM, 0); if(cfd < 0) { ERR_MSG("socket"); return -1; } printf("socket create success cfd=%d\n", cfd); //填充地址信息结构体给sendto函数使用,想发给谁就填谁的地址信息 //真实的地址信息结构体根据地址族指定 AF_INET: man 7 IP struct sockaddr_in sin; sin.sin_family = AF_INET; //必须填AF_INET; sin.sin_port = htons(SER_PORT); //对端绑定的端口号 sin.sin_addr.s_addr = inet_addr(SER_IP); //对端绑定的IP struct sockaddr_in rcvaddr; socklen_t addrlen = sizeof(rcvaddr); char buf[128] = ""; ssize_t res ; while(1) { bzero(buf, sizeof(buf)); printf("请输入>>> "); fgets(buf, sizeof(buf), stdin); buf[strlen(buf)-1] = 0; //发送数据, 主动发送给指定接收放,例如这里可以主动发给服务器 if(sendto(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("sendto"); return -1; } printf("sendto success\n"); bzero(buf, sizeof(buf)); res = recvfrom(cfd, buf, sizeof(buf), 0, (struct sockaddr*)&rcvaddr, &addrlen); if(res < 0) { ERR_MSG("recvfrom"); return -1; } printf("[%s:%d] : %s\n", \ inet_ntoa(rcvaddr.sin_addr), ntohs(rcvaddr.sin_port), buf); } //关闭套接字 close(cfd); return 0; }
UDP服务器与客户端区别不会很明显。
2.1TCP服务器
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h> #define PORT 8888 #define IP "192.168.124.34" #define ERR_MSG(msg) {fprintf(stderr, "line:%d ", __LINE__);\ perror(msg);\ } int main(int argc, const char *argv[]) { //创建流式套接字 int sfd = socket(AF_INET, SOCK_STREAM, 0); if(sfd < 0) { ERR_MSG("socket"); return -1; } printf("流式套接字创建完毕 sfd=%d\n", sfd); //允许端口快速被复用 int reuse = 1; if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { ERR_MSG("setsockopt"); return -1; } printf("允许端口快速复用成功\n"); //填充地址信息结构体,给bind使用 //真实的地址信息结构体根据地址族制定 AF_INET-->man 7 ip struct sockaddr_in sin; sin.sin_family =AF_INET; sin.sin_port = htons(PORT); sin.sin_addr.s_addr = inet_addr(IP); //绑定服务器地址,必须绑定 if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("bind"); return -1; } printf("绑定成功\n"); //将套接字设置为监听状态 if(listen(sfd, 128) < 0) { ERR_MSG("listen"); return -1; } printf("监听成功\n"); //获取连接成功的客户端信息 //生成一个新的套接字文件描述符 struct sockaddr_in cin; //存储客户端信息 socklen_t addrlen = sizeof(cin); int newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen); if(newfd < 0) { ERR_MSG("accept"); return -1; } printf("[%s:%d] newfd=%d 客户端连接成功\n",\ inet_ntoa(cin.sin_addr) , ntohs(cin.sin_port), newfd); char buf[128] = ""; size_t res ; while(1) { bzero(buf, sizeof(buf)); //接收 res = recv(newfd, buf,sizeof(buf), 0); if(res < 0) { ERR_MSG("recv"); return -1; } else if(0 == res) { printf("[%s:%d] newfd=%d 客户端下线\n",\ inet_ntoa(cin.sin_addr) , ntohs(cin.sin_port), newfd); break; } printf("[%s:%d] newfd=%d : %s\n",\ inet_ntoa(cin.sin_addr) , ntohs(cin.sin_port), newfd,buf); //发送 if(send(newfd, buf, sizeof(buf), 0) < 0) { ERR_MSG("send"); return -1; } printf("发送成功\n"); } //关闭文件描述符 if(close(sfd) < 0) { ERR_MSG("close"); return -1; } return 0; }
2.2TCP客户端
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <unistd.h> #include <string.h> #define ERR_MSG(msg) do{\ fprintf(stderr, "__%d__ ", __LINE__);\ perror(msg);\ }while(0) #define SER_PORT 8888 //服务器绑定的端口号 #define SER_IP "192.168.124.34" //服务器绑定的IP int main(int argc, const char *argv[]) { //创建流式套接字 int cfd = socket(AF_INET, SOCK_STREAM, 0); if(cfd < 0) { ERR_MSG("socket"); return -1; } printf("socket 创建成功 cfd=%d\n", cfd); //允许端口快速复用 int reuse = 1; if(setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) { ERR_MSG("setsockopt"); return -1; } printf("允许端口快速复用成功\n"); //绑定客户端的地址信息---》非必须绑定 //客户端若不绑定,则操作系统会自动给客户端绑定本机IP及随机端口 //填充服务器的地址信息结构体给connect函数使用; //真实的地址信息结构体根据地址族指定,AF_INET:man 7 ip struct sockaddr_in sin; sin.sin_family = AF_INET; //必须填AF_INET; sin.sin_port = htons(SER_PORT); //服务器绑定的端口号 sin.sin_addr.s_addr = inet_addr(SER_IP); //服务器绑定的IP //连接服务器,想要连接哪个服务器就需要填充哪个服务器绑定的地址信息 if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { ERR_MSG("connect"); return -1; } printf("连接服务器成功\n"); char buf[128] = ""; ssize_t res = 0; while(1) { bzero(buf, sizeof(buf)); printf("请输入>>> "); fgets(buf, sizeof(buf), stdin); buf[strlen(buf)-1] = '\0'; //发送数据 if(send(cfd, buf, sizeof(buf), 0) < 0) //if(write(cfd, buf, sizeof(buf)) < 0) { ERR_MSG("send"); return -1; } printf("发送成功\n"); bzero(buf, sizeof(buf)); //接收数据 res = recv(cfd, buf, sizeof(buf), 0); //res = read(cfd, buf, sizeof(buf)); if(res < 0) { ERR_MSG("recv"); return -1; } else if(0 == res) { printf("[%s:%d] cfd=%d 服务器下线__%d__\n", \ SER_IP, SER_PORT, cfd, __LINE__); break; } printf("[%s:%d] cfd=%d :%s __%d__\n", \ SER_IP, SER_PORT, cfd, buf, __LINE__); } //关闭套接字 close(cfd); return 0; }