Socket网络编程:互相通讯
基于UDP的Windows通信
客户端:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") #define SERVERIP "127.0.0.1" #define SERVER_PORT 23333 #define BUFSIZ 4096 int main() { printf("【客户端:目标IP 127.0.0.1,目标端口:23333】\n\n"); //初始化Winsock DLL int ret; WORD sockertVersion=MAKEWORD(2, 2); WSADATA wsaData; ret = WSAStartup(sockertVersion, &wsaData); if(ret!=0) { printf("无法打开winsock.dll!\n"); exit(-1); } //创建socket SOCKET tsocket = socket(AF_INET, SOCK_DGRAM, 0); if(tsocket == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //绑定和发送数据 char buffer[BUFSIZ]; printf("输入数据>>"); scanf("%s",buffer); struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr=inet_addr(SERVERIP); servaddr.sin_port = htons(SERVER_PORT); int num=0; int len = sizeof(struct sockaddr_in); num = sendto(tsocket,buffer, strlen(buffer) , 0, (struct sockaddr*)&servaddr, len); if(num!=strlen(buffer)) { printf("发送数据失败!"); exit(-1); } //接收数据 char buf[BUFSIZ]; num=0; struct sockaddr_in clientaddr; ZeroMemory(&clientaddr,sizeof(clientaddr)); ZeroMemory(buf,sizeof(buf)); num = recvfrom(tsocket,buf,sizeof(buf),0,(struct sockaddr*)&clientaddr,&len); if(num<0) { printf("接收数据失败"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } closesocket(tsocket); WSACleanup(); system("pause"); return 0; }
客户端2.0:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") char *SERVERIP="127.0.0.1"; int SERVER_PORT=23334; int my_BUFSIZ=4096; void binner() { printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } int main(int argc,char *argv[]) { binner(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-l:服务器地址,默认127.0.0.1\n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); exit(-1); } for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-l")==0) { SERVERIP = argv[i+1]; } } } printf("【客户端:目标IP %s,监听端口 %d,发送数据大小:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ); //初始化Winsock DLL int ret; WORD sockertVersion=MAKEWORD(2, 2); WSADATA wsaData; ret = WSAStartup(sockertVersion, &wsaData); if(ret!=0) { printf("无法打开winsock.dll!\n"); exit(-1); } //创建socket SOCKET tsocket = socket(AF_INET, SOCK_DGRAM, 0); if(tsocket == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //绑定和发送数据 char buffer[my_BUFSIZ]; printf("输入数据>>"); gets(buffer); struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr=inet_addr(SERVERIP); servaddr.sin_port = htons(SERVER_PORT); int num=0; int len = sizeof(struct sockaddr_in); num = sendto(tsocket,buffer, strlen(buffer) , 0, (struct sockaddr*)&servaddr, len); if(num!=strlen(buffer)) { printf("发送数据失败!"); exit(-1); } //接收数据 char buf[my_BUFSIZ]; ZeroMemory(buf,sizeof(buf)); num=0; struct sockaddr_in clientaddr; ZeroMemory(&clientaddr,sizeof(clientaddr)); num = recvfrom(tsocket,buf,sizeof(buf),0,(struct sockaddr*)&clientaddr,&len); if(num<0) { printf("接收数据失败"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } closesocket(tsocket); WSACleanup(); system("pause"); return 0; }
服务器端:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") #define BUFSIZ 4096 #define SERVER_PORT 23333 int main() { printf("【服务端:监听端口 23333】\n\n"); //步骤1:使用WSAStartup函数初始化Winsock DLL; WORD scoketVersion; scoketVersion = MAKEWORD(2, 2); WSADATA wsaData; int ret = WSAStartup(scoketVersion, &wsaData); if(ret != 0 ) { printf("无法打开 winsock.dll!\n"); exit(-1); } //步骤2:调用socket函数创建服务器端UDP套接字; SOCKET msock; msock = socket(AF_INET, SOCK_DGRAM, 0); if(msock == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //步骤3:调用bind()函数将该UDP套接字绑定到本机的一个可用的端点地址: struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); if(bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))< 0) { printf("绑定服务器端口:%d失败\n",SERVER_PORT); exit(-1); } //步骤4:调用revfrom函数从该UDP套接字接收来自远程客户端的数据并存入缓冲区,同时获得远程客户端的套接字端点地址并保存; char buf[BUFSIZ]; int num=0; struct sockaddr_in clientaddr; int len = sizeof(clientaddr); ZeroMemory(&clientaddr,sizeof(clientaddr)); ZeroMemory(buf,sizeof(buf)); num = recvfrom(msock, buf, sizeof(buf), 0, (struct sockaddr*)&clientaddr, &len); if(num<0) { printf("接收数据失败\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤5:基于保存的远程客户端的套接字端点地址,调用sendto()函 数将缓冲区中的数据从该UDP套接字发送给该远程客户端; ZeroMemory(buf,sizeof(buf)); printf("输入数据>>"); scanf("%s",buf); if(sendto(msock,buf,strlen(buf),0,(struct sockaddr*)&clientaddr,len)<0) { printf("发送数据失败!"); exit(-1); } //步骤6:与客户交互完毕,调用closesocket()函数将该UDP套接字关闭,释放所占用的系统资源; closesocket(msock); //步骤7:最后,调用WSACleanup0函数结束Winsock Socket API。 WSACleanup(); system("pause"); return 0; }
服务器端2.0:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") int my_BUFSIZ=4096; int SERVER_PORT=23334; void binner() { printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } int main(int argc,char *argv[]) { binner(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); exit(-1); } for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } } } printf("【服务端:监听端口 %d,发送数据大小:%d】\n\n",SERVER_PORT,my_BUFSIZ); //步骤1:使用WSAStartup函数初始化Winsock DLL; WORD scoketVersion; scoketVersion = MAKEWORD(2, 2); WSADATA wsaData; int ret = WSAStartup(scoketVersion, &wsaData); if(ret != 0 ) { printf("无法打开 winsock.dll!\n"); exit(-1); } //步骤2:调用socket函数创建服务器端UDP套接字; SOCKET msock; msock = socket(AF_INET, SOCK_DGRAM, 0); if(msock == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //步骤3:调用bind()函数将该UDP套接字绑定到本机的一个可用的端点地址: struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); if(bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))< 0) { printf("绑定服务器端口:%d失败\n",SERVER_PORT); exit(-1); } //步骤4:调用revfrom函数从该UDP套接字接收来自远程客户端的数据并存入缓冲区,同时获得远程客户端的套接字端点地址并保存; char buf[my_BUFSIZ]; int num=0; struct sockaddr_in clientaddr; int len = sizeof(clientaddr); ZeroMemory(&clientaddr,sizeof(clientaddr)); ZeroMemory(buf,sizeof(buf)); num = recvfrom(msock, buf, sizeof(buf), 0, (struct sockaddr*)&clientaddr, &len); if(num<0) { printf("接收数据失败\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤5:基于保存的远程客户端的套接字端点地址,调用sendto()函 数将缓冲区中的数据从该UDP套接字发送给该远程客户端; ZeroMemory(buf,sizeof(buf)); printf("输入数据>>"); gets(buf); if(sendto(msock,buf,strlen(buf),0,(struct sockaddr*)&clientaddr,len)<0) { printf("发送数据失败!"); exit(-1); } //步骤6:与客户交互完毕,调用closesocket()函数将该UDP套接字关闭,释放所占用的系统资源; closesocket(msock); //步骤7:最后,调用WSACleanup0函数结束Winsock Socket API。 WSACleanup(); system("pause"); return 0; }
基于TCP的Windows通信
客户端:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") #define SERVERIP "127.0.0.1" #define SERVER_PORT 23334 #define BUFSIZ 4096 int main() { printf("【客户端:目标IP 127.0.0.1,目标端口:23334】\n\n"); //步骤1:使用WSAStartup()函数初始化Winsock DLL; int ret; WORD socketVersion=MAKEWORD(2, 2); WSADATA wsaData; ret = WSAStartup(socketVersion, &wsaData); if(ret!=0) { printf("无法打开winsock.dll!\n"); exit(-1); } //步骤2:调用socket()函数创建客户端TCP套接字; SOCKET tsocket = socket(AF_INET, SOCK_STREAM, 0); if(tsocket == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //步骤3:找到期望与之通信的远程服务器端套接字的端点地址(即远程服务器端的IP地址和协议端口号), //然后再调用connect()函数向远程服务器端发起TCP连接建立请求; struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr=inet_addr(SERVERIP); servaddr.sin_port = htons(SERVER_PORT); if(connect(tsocket,(struct sockaddr*)&servaddr,sizeof(struct sockaddr))<0) { printf("连接失败!"); exit(-1); } //步骤4:在与服务器端成功地建立了TCP连接之后, //调用send()函数将缓冲区中的数据从该TCP套接字发送给该远程服务器端; char buffer[BUFSIZ]; printf("输入数据>>"); scanf("%s",buffer); // char *buffer="这里是客户端~"; int num=0; num = send(tsocket,buffer, strlen(buffer),0); if(num!=strlen(buffer)) { printf("发送数据失败!"); exit(-1); } //步骤5:调用recv()函数从该TCP套接字读取服务器端发送过来的数据并存入缓冲区; char buf[BUFSIZ]; num=0; ZeroMemory(buf,sizeof(buf)); num = recv(tsocket,buf,sizeof(buf),0); if(num<0) { printf("接收数据失败"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤6:与服务器端交互完毕,调用closesocket()函数将该 TCP套接字关闭并释放所占用的系统资源; closesocket(tsocket); //步骤7:最后,调用WSACleanup()函数结束Winsock Socket API。 WSACleanup(); system("pause"); return 0; }
客户端2.0:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") char *SERVERIP="127.0.0.1"; int SERVER_PORT=23334; int my_BUFSIZ=4096; void binner() { printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } int main(int argc,char *argv[]) { binner(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-l:服务器地址,默认127.0.0.1\n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); exit(-1); } for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-l")==0) { SERVERIP = argv[i+1]; } } } printf("【客户端:目标IP %s,监听端口 %d,发送数据大小:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ); //步骤1:使用WSAStartup()函数初始化Winsock DLL; int ret; WORD socketVersion=MAKEWORD(2, 2); WSADATA wsaData; ret = WSAStartup(socketVersion, &wsaData); if(ret!=0) { printf("无法打开winsock.dll!\n"); exit(-1); } //步骤2:调用socket()函数创建客户端TCP套接字; SOCKET tsocket = socket(AF_INET, SOCK_STREAM, 0); if(tsocket == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //步骤3:找到期望与之通信的远程服务器端套接字的端点地址(即远程服务器端的IP地址和协议端口号), //然后再调用connect()函数向远程服务器端发起TCP连接建立请求; struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr=inet_addr(SERVERIP); servaddr.sin_port = htons(SERVER_PORT); if(connect(tsocket,(struct sockaddr*)&servaddr,sizeof(struct sockaddr))<0) { printf("连接失败!"); exit(-1); } //步骤4:在与服务器端成功地建立了TCP连接之后, //调用send()函数将缓冲区中的数据从该TCP套接字发送给该远程服务器端; char buffer[my_BUFSIZ]; printf("输入数据>>"); scanf("%s",buffer); // char *buffer="这里是客户端~"; int num=0; num = send(tsocket,buffer, strlen(buffer),0); if(num!=strlen(buffer)) { printf("发送数据失败!"); exit(-1); } //步骤5:调用recv()函数从该TCP套接字读取服务器端发送过来的数据并存入缓冲区; char buf[my_BUFSIZ]; num=0; ZeroMemory(buf,sizeof(buf)); num = recv(tsocket,buf,sizeof(buf),0); if(num<0) { printf("接收数据失败"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤6:与服务器端交互完毕,调用closesocket()函数将该 TCP套接字关闭并释放所占用的系统资源; closesocket(tsocket); //步骤7:最后,调用WSACleanup()函数结束Winsock Socket API。 WSACleanup(); system("pause"); return 0; }
服务器端:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") #define BUFSIZ 4096 #define SERVER_PORT 23334 int main() { //步骤1:使用WSAStartup()函数初始化Winsock DLL; printf("【服务端:监听端口 23334】\n\n"); WORD scoketVersion; scoketVersion = MAKEWORD(2, 2); WSADATA wsaData; int ret = WSAStartup(scoketVersion, &wsaData); if(ret != 0 ) { printf("无法打开 winsock.dll!\n"); exit(-1); } //步骤2:调用socket()函数创建服务器端TCP主套接字; SOCKET msock; msock = socket(AF_INET, SOCK_STREAM, 0); if(msock == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //步骤3:调用bind()函数将TCP主套接字绑定到本机的一个可用的端点地址: struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); ret = bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); if(ret < 0) { printf("绑定服务器端口:%d失败\n",SERVER_PORT); exit(-1); } //步骤4:调用listen()函数将该TCP主套核字设为被动模式,并设置等待队列长度: #define QUEUE 20 if(listen(msock,QUEUE)<0) { printf("监听失败!"); exit(-1); } //步骤5:调用accpet()函数从该TCP主套接字上接收一个新的客户 TCP连接请求, //并在与该客户之间成功建立了TCP连接之后,为该TCP连接创建一一个新的从套接字 //(由该新的从套接字来负责与客户之间进行实际的通信); SOCKET ssock; struct sockaddr_in clientaddr; int len = sizeof(clientaddr); ZeroMemory(&clientaddr,sizeof(clientaddr)); ssock=accept(msock,(struct sockaddr*)&clientaddr,&len); if(ssock==INVALID_SOCKET) { printf("接收数据失败\n"); exit(-1); } //步骤6:基于新创建的从套接字,调用recv()函数利用 该从套接字读取客户端发送过来的数据并存入缓冲区; char buf[BUFSIZ]; ZeroMemory(buf,sizeof(buf)); if(recv(ssock, buf, sizeof(buf), 0)<0) { printf("接收数据失败\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤7:基于新创建的从套接字,调用send()函数将缓冲区中的数据利用该从套接字发送给该远程客户端; //char *buffer="这里是服务器~"; char buffer[BUFSIZ]; printf("输入数据>>"); scanf("%s",buffer); if(send(ssock,buffer,strlen(buffer),0)!=strlen(buffer)) { printf("发送数据失败!"); exit(-1); } //步骤8:与客户交互完毕,调用closesocket()函数将该从套接字关闭,释放所占用的系统资源); closesocket(ssock); //步骤9:最后,当与所有客户交互完毕之后,调用closesocket()函数将TCP主套接字关闭, //释放所古用的系统资源,然后,再调用WSACleanup()函数来结束Winsock Socket API closesocket(msock); WSACleanup(); system("pause"); return 0; }
服务器端2.0:
#include <stdio.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") int my_BUFSIZ=4096; int SERVER_PORT=23334; void binner() { printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } int main(int argc,char *argv[]) { binner(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); exit(-1); } for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } } } //步骤1:使用WSAStartup()函数初始化Winsock DLL; printf("【服务端:监听端口 %d,发送数据大小:%d】\n\n",SERVER_PORT,my_BUFSIZ); WORD scoketVersion; scoketVersion = MAKEWORD(2, 2); WSADATA wsaData; int ret = WSAStartup(scoketVersion, &wsaData); if(ret != 0 ) { printf("无法打开 winsock.dll!\n"); exit(-1); } //步骤2:调用socket()函数创建服务器端TCP主套接字; SOCKET msock; msock = socket(AF_INET, SOCK_STREAM, 0); if(msock == INVALID_SOCKET) { printf("创建socket失败!"); exit(-1); } //步骤3:调用bind()函数将TCP主套接字绑定到本机的一个可用的端点地址: struct sockaddr_in servaddr; ZeroMemory(&servaddr,sizeof(servaddr)); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); ret = bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); if(ret < 0) { printf("绑定服务器端口:%d失败\n",SERVER_PORT); exit(-1); } //步骤4:调用listen()函数将该TCP主套核字设为被动模式,并设置等待队列长度: #define QUEUE 20 if(listen(msock,QUEUE)<0) { printf("监听失败!"); exit(-1); } //步骤5:调用accpet()函数从该TCP主套接字上接收一个新的客户 TCP连接请求, //并在与该客户之间成功建立了TCP连接之后,为该TCP连接创建一一个新的从套接字 //(由该新的从套接字来负责与客户之间进行实际的通信); SOCKET ssock; struct sockaddr_in clientaddr; int len = sizeof(clientaddr); ZeroMemory(&clientaddr,sizeof(clientaddr)); ssock=accept(msock,(struct sockaddr*)&clientaddr,&len); if(ssock==INVALID_SOCKET) { printf("接收数据失败\n"); exit(-1); } //步骤6:基于新创建的从套接字,调用recv()函数利用 该从套接字读取客户端发送过来的数据并存入缓冲区; char buf[my_BUFSIZ]; ZeroMemory(buf,sizeof(buf)); if(recv(ssock, buf, sizeof(buf), 0)<0) { printf("接收数据失败\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤7:基于新创建的从套接字,调用send()函数将缓冲区中的数据利用该从套接字发送给该远程客户端; //char *buffer="这里是服务器~"; char buffer[my_BUFSIZ]; printf("输入数据>>"); scanf("%s",buffer); if(send(ssock,buffer,strlen(buffer),0)!=strlen(buffer)) { printf("发送数据失败!"); exit(-1); } //步骤8:与客户交互完毕,调用closesocket()函数将该从套接字关闭,释放所占用的系统资源); closesocket(ssock); //步骤9:最后,当与所有客户交互完毕之后,调用closesocket()函数将TCP主套接字关闭, //释放所古用的系统资源,然后,再调用WSACleanup()函数来结束Winsock Socket API closesocket(msock); WSACleanup(); system("pause"); return 0; }
基于UDP的Linux通信
客户端:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> int main() { printf("【客户端:目标IP 127.0.0.1,目标端口:23333】\n\n"); //步骤1:调用socket()函数创建客户端UDP套接字; int tsock; tsock = socket(AF_INET,SOCK_DGRAM,0); if(tsock < 0) { printf("创建套接字失败\n"); exit(-1); } //步骤2:找到期望与之通信的远程服务器的IP地址和协议端口号,然后再调用sendto()函数将缓冲区中的数据从UDP套接字发送给远程服务器端; #define SERVERIP "127.0.0.1" #define SERVER_PORT 23333 char buffer[BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); printf("输入数据>>"); scanf("%s",buffer); struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; inet_aton(SERVERIP,&servaddr.sin_addr); servaddr.sin_port = htons(SERVER_PORT); int len = sizeof(struct sockaddr_in); if(sendto(tsock,buffer,strlen(buffer),0,(struct sockaddr*)&servaddr,len) != strlen(buffer)) { printf("发送数据失败\n"); exit(-1); } //步骤3:调用revfrom()函数从该UDP套接字接收来自远程服务器端的数据并存入缓冲区; #define BUFSIZE 4096 char buf[BUFSIZE]; struct sockaddr_in clientaddr; memset(&clientaddr,0,sizeof(struct sockaddr_in)); memset(buf,'\0',sizeof(buf)); if(recvfrom(tsock,buf,sizeof(buf),0,(struct sockaddr*)&clientaddr,&len) < 0) { printf("接收数据失败\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } close(tsock); return 0; }
客户端2.0:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> char *SERVERIP="127.0.0.1"; int SERVER_PORT=23334; int my_BUFSIZ=4096; void binner() { printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } int main(int argc,char *argv[]) { binner(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-l:服务器地址,默认127.0.0.1\n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); exit(-1); } for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-l")==0) { SERVERIP = argv[i+1]; } } } printf("【客户端:目标IP %s,监听端口 %d,发送数据大小:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ); //步骤1:调用socket()函数创建客户端UDP套接字; int tsock; tsock = socket(AF_INET,SOCK_DGRAM,0); if(tsock < 0) { printf("创建套接字失败\n"); exit(-1); } //步骤2:找到期望与之通信的远程服务器的IP地址和协议端口号,然后再调用sendto()函数将缓冲区中的数据从UDP套接字发送给远程服务器端; char buffer[BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); printf("输入数据>>"); gets(buffer); struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; inet_aton(SERVERIP,&servaddr.sin_addr); servaddr.sin_port = htons(SERVER_PORT); int len = sizeof(struct sockaddr_in); if(sendto(tsock,buffer,strlen(buffer),0,(struct sockaddr*)&servaddr,len) != strlen(buffer)) { printf("发送数据失败\n"); exit(-1); } //步骤3:调用revfrom()函数从该UDP套接字接收来自远程服务器端的数据并存入缓冲区; char buf[my_BUFSIZ]; struct sockaddr_in clientaddr; memset(&clientaddr,0,sizeof(struct sockaddr_in)); memset(buf,'\0',sizeof(buf)); if(recvfrom(tsock,buf,sizeof(buf),0,(struct sockaddr*)&clientaddr,&len) < 0) { printf("接收数据失败\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } close(tsock); return 0; }
服务器端:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <unistd.h> #include <netinet/in.h> #include <stdlib.h> int main() { printf("【UDP服务端:监听端口 23333】\n\n"); //步骤1: 调用socket()函数创建服务器端UDP套接字; int msocket; msocket = socket(AF_INET,SOCK_DGRAM,0); if(msocket<0) { printf("创建套接字失败"); exit(-1); } //步骤2:调用bind()函数将该UDP套接字绑定到本机的一个可用的端点地址; #define SERVER_PORT 23333 int ret; struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); ret=bind(msocket,(struct sockaddr*)&servaddr,sizeof(struct sockaddr_in)); if(ret<0) { printf("服务器绑定端口:%d失败",SERVER_PORT); exit(-1); } //步骤3:调用recvfrom函数从该UDP套接字接收来自远程客户端的数据并存入缓冲区,同时获得远程客户端的套接字端点地址并保存; #define BUFSIZE 4096 char buf[BUFSIZE]; memset(buf,'\0',sizeof(buf)); struct sockaddr_in clientaddr; int len = sizeof(clientaddr); memset(&clientaddr,0,sizeof(struct sockaddr_in)); if(recvfrom(msocket, buf, sizeof(buf), 0, (struct sockaddr*)&clientaddr, &len)<0) { printf("接收数据失败\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤4:基于保存的远程客户端的套接字端点地址,调用sendto函数将缓冲区中的数据从该UDP套接字发送给该远程客户端; memset(buf,'\0',sizeof(buf)); printf("输入数据>>"); scanf("%s",buf); if(sendto(msocket,buf,strlen(buf),0,(struct sockaddr*)&clientaddr,len)!=strlen(buf)) { printf("发送数据失败!"); exit(-1); } //步骤5:与客户交互完毕,调用close()函数将该 UDP套接字关闭,释放所占用的系统资源。 close(msocket); return 0; }
服务器端2.0:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <unistd.h> #include <netinet/in.h> #include <stdlib.h> int my_BUFSIZ=4096; int SERVER_PORT=23334; void binner() { printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } int main(int argc,char *argv[]) { binner(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); exit(-1); } for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } } } printf("【UDP服务端:监听端口 %d,发送数据大小:%d】\n\n",SERVER_PORT,my_BUFSIZ); //步骤1: 调用socket()函数创建服务器端UDP套接字; int msocket; msocket = socket(AF_INET,SOCK_DGRAM,0); if(msocket<0) { printf("创建套接字失败"); exit(-1); } //步骤2:调用bind()函数将该UDP套接字绑定到本机的一个可用的端点地址; int ret; struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); ret=bind(msocket,(struct sockaddr*)&servaddr,sizeof(struct sockaddr_in)); if(ret<0) { printf("服务器绑定端口:%d失败",SERVER_PORT); exit(-1); } //步骤3:调用recvfrom函数从该UDP套接字接收来自远程客户端的数据并存入缓冲区,同时获得远程客户端的套接字端点地址并保存; char buf[my_BUFSIZ]; memset(buf,'\0',sizeof(buf)); struct sockaddr_in clientaddr; int len = sizeof(clientaddr); memset(&clientaddr,0,sizeof(struct sockaddr_in)); if(recvfrom(msocket, buf, sizeof(buf), 0, (struct sockaddr*)&clientaddr, &len)<0) { printf("接收数据失败\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤4:基于保存的远程客户端的套接字端点地址,调用sendto函数将缓冲区中的数据从该UDP套接字发送给该远程客户端; memset(buf,'\0',sizeof(buf)); printf("输入数据>>"); gets(buf); if(sendto(msocket,buf,strlen(buf),0,(struct sockaddr*)&clientaddr,len)!=strlen(buf)) { printf("发送数据失败!"); exit(-1); } //步骤5:与客户交互完毕,调用close()函数将该 UDP套接字关闭,释放所占用的系统资源。 close(msocket); return 0; }
基于TCP的Linux通信
客户端:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> #define BUFSIZE 4096 int SERVER_PORT= 23335; int main() { //步骤1:调用socket函数创建客户端TCP套接字; printf("输入通信端口:"); scanf("%d",&SERVER_PORT); printf("\n\t【客户端:目标IP 127.0.0.1,目标端口:%d】\n\n",SERVER_PORT); int tsock; tsock = socket(AF_INET,SOCK_STREAM,0); if(tsock < 0) { printf("创建socket失败!\n"); exit(-1); } //步骤2:找到期望与之通信的远程服务器端套接字的端点地址(即服务器端的IP地址和协议端口号);然后,调用connect函数向远程服务器端发起TCP连接建立请求; #define SERVERIP "127.0.0.1" struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; inet_aton(SERVERIP,&servaddr.sin_addr); servaddr.sin_port = htons(SERVER_PORT); int ret; ret = connect(tsock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr)); if(ret < 0) { printf("连接失败!\n"); exit(-1); } //步骤3:在与服务器端成功地建立了TCP连接之后,调用send()函数将缓冲区中的数据从套接字发送给该远程服务器端; char buffer[BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); printf("输入数据>>"); scanf("%s",buffer); int num = 0; num = send(tsock,buffer,strlen(buffer),0); if(num != strlen(buffer)) { printf("发送数据失败!\n"); exit(-1); } //步骤4:调用recv()函数从套接字读取服务器端发送过来的数据并存入缓冲区; char buf[BUFSIZE]; memset(buf,'\0',sizeof(buf)); num = 0; num = recv(tsock,buf,sizeof(buf),0); if(num < 0) { printf("接收数据失败!\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤5:与服务器端交互完毕,调用close()函数将套接字关闭,释放所占用的系统资源。 close(tsock); }
客户端2.0:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> char *SERVERIP="127.0.0.1"; int SERVER_PORT=23334; int my_BUFSIZ=4096; void binner() { printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } int main(int argc,char *argv[]) { binner(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-l:服务器地址,默认127.0.0.1\n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); exit(-1); } for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } else if(strcmp(argv[i],"-l")==0) { SERVERIP = argv[i+1]; } } } //步骤1:调用socket函数创建客户端TCP套接字; printf("【客户端:目标IP %s,监听端口 %d,发送数据大小:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ); int tsock; tsock = socket(AF_INET,SOCK_STREAM,0); if(tsock < 0) { printf("创建socket失败!\n"); exit(-1); } //步骤2:找到期望与之通信的远程服务器端套接字的端点地址(即服务器端的IP地址和协议端口号);然后,调用connect函数向远程服务器端发起TCP连接建立请求; struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_family = AF_INET; inet_aton(SERVERIP,&servaddr.sin_addr); servaddr.sin_port = htons(SERVER_PORT); int ret; ret = connect(tsock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr)); if(ret < 0) { printf("连接失败!\n"); exit(-1); } //步骤3:在与服务器端成功地建立了TCP连接之后,调用send()函数将缓冲区中的数据从套接字发送给该远程服务器端; char buffer[BUFSIZ]; memset(buffer,'\0',sizeof(buffer)); printf("输入数据>>"); gets(buffer); int num = 0; num = send(tsock,buffer,strlen(buffer),0); if(num != strlen(buffer)) { printf("发送数据失败!\n"); exit(-1); } //步骤4:调用recv()函数从套接字读取服务器端发送过来的数据并存入缓冲区; char buf[my_BUFSIZ]; memset(buf,'\0',sizeof(buf)); num = 0; num = recv(tsock,buf,sizeof(buf),0); if(num < 0) { printf("接收数据失败!\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤5:与服务器端交互完毕,调用close()函数将套接字关闭,释放所占用的系统资源。 close(tsock); }
服务器端:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> int SERVER_PORT = 23335 ; int main() { printf("输入通信端口:"); scanf("%d",&SERVER_PORT); printf("\n\t【TCP服务端:监听端口 %d】\n\n",SERVER_PORT); //步骤1:调用socket()函数创建服务器端TCP主套接字; int msock; msock = socket(AF_INET,SOCK_STREAM,0); if(msock<0) { printf("创建套接字失败"); exit(-1); } //步骤2:调用bind()函数将该TCP套接字绑定到本机的一个可用的端点地址; struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); int ret = bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); if(ret < 0) { printf("绑定服务器端口:%d失败\n",SERVER_PORT); exit(-1); } //步骤3:调用lsten函数将该TCP套接字设为被动模式,并设置等待队列的长度; #define QUEUE 20 if(listen(msock,QUEUE)<0) { printf("监听失败!\n"); exit(-1); } //步骤4:调用accept()函数从该TCP套接字上接收一个新客户连接请求,并且在与该客户之间成功建立了TCP 连接之后,为该TCP连接创建个新的从套接字 (由该新套接字来负责与客户之间进行实际的通信); int ssock; struct sockaddr_in clientaddr; int len = sizeof(clientaddr); memset(&clientaddr,0,sizeof(struct sockaddr_in)); ssock=accept(msock,(struct sockaddr*)&clientaddr,&len); if(ssock<0) { printf("接收数据失败\n"); exit(-1); } //步骤5:基于新创建的从套接字,调用recv(函数从套接字读取客户发送过来的数据并存入缓冲区; #define BUFSIZ 4096 char buf[BUFSIZ]; memset(buf,'\0',sizeof(buf)); if(recv(ssock, buf, sizeof(buf), 0)<0) { printf("接收数据失败\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤6:基于新创建的从套接字,调用send()函 数将缓冲区中的数据从套接字发送给该远程客户: char buffer[BUFSIZ]; printf("输入数据>>"); scanf("%s",buffer); if(send(ssock,buffer,strlen(buffer),0)!=strlen(buffer)) { printf("发送数据失败!"); exit(-1); } //步骤7:与客户交互完毕,调用close()函数将从套接字关闭,释放所占用的系统资源; close(ssock); //步骤8:与所有客户交互完毕,调用close()函数将主套接字关闭,释放所占用的系统资源 close(msock); return 0; }
服务器端2.0:
#include <stdio.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <stdlib.h> #include <string.h> int SERVER_PORT = 23335 ; int my_BUFSIZ=4096; void binner() { printf(" _ _ _ _ _ _ _ _ \n"); printf(" (_)(_)(_)(_) _ (_)_ _(_) (_)_ _(_)\n"); printf(" (_) (_) (_)_ _(_) (_)_ _(_) \n"); printf(" (_) _ _ _ (_) (_)_(_) (_)_(_) \n"); printf(" (_)(_)(_)(_) _(_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) _ _(_) (_)_ (_) \n"); printf(" (_) (_) (_) (_) (_) \n"); printf(" \n"); } int main(int argc,char *argv[]) { binner(); if(argc>1) { if(strcmp(argv[1],"-h")==0) { printf("\n使用说明:\n"); printf("-h:帮助 \n"); printf("-p:端口,默认23334 \n"); printf("-b:发送数据大小,默认4096\n"); exit(-1); } for(int i=1;i<argc;++i) { if(strcmp(argv[i],"-p")==0) { SERVER_PORT=atoi(argv[i+1]); } else if(strcmp(argv[i],"-b")==0) { my_BUFSIZ=atoi(argv[i+1]); } } } printf("【TCP服务端:监听端口 %d,发送数据大小:%d】\n\n",SERVER_PORT,my_BUFSIZ); //步骤1:调用socket()函数创建服务器端TCP主套接字; int msock; msock = socket(AF_INET,SOCK_STREAM,0); if(msock<0) { printf("创建套接字失败"); exit(-1); } //步骤2:调用bind()函数将该TCP套接字绑定到本机的一个可用的端点地址; struct sockaddr_in servaddr; memset(&servaddr,0,sizeof(struct sockaddr_in)); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(SERVER_PORT); int ret = bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in)); if(ret < 0) { printf("绑定服务器端口:%d失败\n",SERVER_PORT); exit(-1); } //步骤3:调用lsten函数将该TCP套接字设为被动模式,并设置等待队列的长度; #define QUEUE 20 if(listen(msock,QUEUE)<0) { printf("监听失败!\n"); exit(-1); } //步骤4:调用accept()函数从该TCP套接字上接收一个新客户连接请求,并且在与该客户之间成功建立了TCP 连接之后,为该TCP连接创建个新的从套接字 (由该新套接字来负责与客户之间进行实际的通信); int ssock; struct sockaddr_in clientaddr; int len = sizeof(clientaddr); memset(&clientaddr,0,sizeof(struct sockaddr_in)); ssock=accept(msock,(struct sockaddr*)&clientaddr,&len); if(ssock<0) { printf("接收数据失败\n"); exit(-1); } //步骤5:基于新创建的从套接字,调用recv(函数从套接字读取客户发送过来的数据并存入缓冲区; char buf[my_BUFSIZ]; memset(buf,'\0',sizeof(buf)); if(recv(ssock, buf, sizeof(buf), 0)<0) { printf("接收数据失败\n"); exit(-1); } else { printf("已接受数据>>%s\n",buf); } //步骤6:基于新创建的从套接字,调用send()函 数将缓冲区中的数据从套接字发送给该远程客户: char buffer[my_BUFSIZ]; printf("输入数据>>"); gets(buffer); if(send(ssock,buffer,strlen(buffer),0)!=strlen(buffer)) { printf("发送数据失败!"); exit(-1); } //步骤7:与客户交互完毕,调用close()函数将从套接字关闭,释放所占用的系统资源; close(ssock); //步骤8:与所有客户交互完毕,调用close()函数将主套接字关闭,释放所占用的系统资源 close(msock); return 0; }