參考鏈接
- send函數和recv函數 – gudako's memo
注意事項
- 代碼很low,主要看封裝的Send函數所體現的切片思想即可
server代碼
//udp服務端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <ctype.h>
#include <string>
#include <iostream>#define SLICE_SIZE 5bool Send(int sock_fd, char* buffer, int length)
{int once; //一次發送的返回值int total = 0; //目前發送了多少數據int thislen = 0; //本次要發送的數據長度do{if (length - total > SLICE_SIZE)thislen = SLICE_SIZE;elsethislen = length - total;once = send(sock_fd, buffer + total, thislen, 0);if (once <= 0) //如果once < 0則表示發送失敗,用break跳出循環,返回FALSE{break;}total += once;} while (total < length); //如果total < length說明數據還未完全發送,繼續循環if (total == length) //當total == length時,說明已完全發送,返回TRUEreturn true;return false;
}int main(int argc, char const *argv[])
{//1.創建socketint cfd = socket(AF_INET,SOCK_DGRAM,0);if(cfd<0){perror("socket error");return -1;}//綁定struct sockaddr_in serv;struct sockaddr_in client;bzero(&serv,sizeof(serv));serv.sin_family = AF_INET;serv.sin_port = htons(7777);serv.sin_addr.s_addr = htonl(INADDR_ANY);bind(cfd,(struct sockaddr *)&serv,sizeof(serv));//3.循環讀取讀取客戶端消息和給客戶端回復消息int i;int n;socklen_t len;char buf[1024];std::string merge;while(1){//4.讀取數據memset(buf,0x00,sizeof(buf));len = sizeof(client);n = recvfrom(cfd,buf,sizeof(buf),0,(struct sockaddr*)&client,&len);merge += buf;printf("serv端口號=[%d]:本次發送字節數=[%d],buf=[%s]\n",ntohs(client.sin_port),n,buf);// printf("serv端口號=[%d]:本次發送字節數=[%d],bufer=[%s]\n",ntohs(serv.sin_port),once,tmp);std::cout << "merge= " << merge << ";" << "merge size is " << merge.size() << std::endl;//5.給客戶端回復消息sendto(cfd,buf,n,0,(struct sockaddr*)&client,len);}//關閉套接字close(cfd);return 0;
}
client代碼
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <ctype.h>#define SLICE_SIZE 5char* buffer = {"Helloworld\n"};
char* tmp[1024] ={0};
struct sockaddr_in serv;
bool Send(int sock_fd, char* buffer, int length)
{int once; //一次發送的返回值int total = 0; //目前發送了多少數據int thislen = 0; //本次要發送的數據長度do{if (length - total > SLICE_SIZE)thislen = SLICE_SIZE;elsethislen = length - total;once = send(sock_fd, buffer + total, thislen, 0);
// printf("serv端口號=[%d]:本次發送字節數=[%d],bufer=[%s]\n",ntohs(serv.sin_port),once,tmp);// sendto(cfd,buf,n,0,(struct sockaddr*)&serv,sizeof(serv));if (once <= 0) //如果once < 0則表示發送失敗,用break跳出循環,返回FALSE{break;}total += once;} while (total < length); //如果total < length說明數據還未完全發送,繼續循環if (total == length) //當total == length時,說明已完全發送,返回TRUEreturn true;return false;
}int main(){//1.創建socketint cfd = socket(AF_INET,SOCK_DGRAM,0);if(cfd<0){perror("socket error");return -1;}int n ;serv.sin_family = AF_INET;serv.sin_port = htons(7777);inet_pton(AF_INET,"127.0.0.1",&serv.sin_addr.s_addr);struct sockaddr_in client;client.sin_family = AF_INET;client.sin_port = htons(3333);bind(cfd, (struct sockaddr*)&client, sizeof(client));connect(cfd, (struct sockaddr*)&serv, sizeof(serv));char buf[1024] = {'\0'};
// while(1){//讀取標準輸入數據
// memset(buf,0x00,sizeof(buf));
// n = read(STDIN_FILENO,buf, sizeof(buf));
// buf[n-1] = 0x00;
// n -= 1;Send(cfd,buffer, strlen(buffer));//發送數據
// sendto(cfd,buf,n,0,(struct sockaddr*)&serv,sizeof(serv));//讀取數據memset(buf,0x00,sizeof(buf));n = recvfrom(cfd,buf,sizeof(buf),0,NULL,NULL);
// printf("[%d]:n=[%d],buf=[%s]\n",ntohs(serv.sin_port),n,buf);
// }//關閉套接字close(cfd);return 0;
}