思維導圖
TCP服務器端和客戶端通訊
服務器端 代碼
#include<myhead.h>
#define SER_IP "192.168.109.12"//我的虛擬機的ip
#define SER_PORT 8888
int main()
{//1.創建一個用于連接的套接字文件描述符int sfd = socket(AF_INET,SOCK_STREAM,0);if(sfd==-1){perror("socket error");return -1;}printf("sfd = %d\n",sfd);//2.給套接字綁定ip地址和的端口號//2.1準備地址信息結構體struct sockaddr_in sin;//通信域地址族sin.sin_family = AF_INET;//服務器端口號sin.sin_port = htons(SER_PORT);//2字節 主機字節序 轉化為 網絡字節序//服務器ip地址sin.sin_addr.s_addr = inet_addr(SER_IP);//ip地址 點分十進制 轉化為 網絡字節序//2.2執行綁定工作if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind error");return -1;}printf("bind success\n");//3.將套接字設置成被動監聽狀態if(listen(sfd,128)==-1){perror("listen error");return -1;}printf("listen success\n");//4.阻塞 等客戶端的連接//4.1 定義地址信息結構體,用于客戶端地址信息struct sockaddr_in cin;socklen_t addrlen = sizeof(cin);//接收地址長度int newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen);if(newfd==-1){perror("accept error");return -1;}printf("[%s:%d]-連接成功newfd = %d\n",\inet_ntoa(cin.sin_addr),\ntohs(cin.sin_port),newfd);//5.實現數據的收發char buf[128]="";while(1){//清空bufbzero(buf,sizeof(buf));//從套接字讀取消息int res=read(newfd,buf,sizeof(buf));if(res==0){printf("客戶端下線\n");close(newfd);//關閉通信套接字break;}printf("[%s:%d] : %s\n",\inet_ntoa(cin.sin_addr),\ntohs(cin.sin_port),buf);//給消息 加個:D還回去strcat(buf,":D");write(newfd,buf,strlen(buf));printf("發送成功\n");}//6.關閉套接字close(sfd);return 0;
}
客戶端 代碼
#include<myhead.h>
#define SER_IP "192.168.109.12" //服務器ip地址
#define SER_PORT 8888 //服務器端口號
#define CLI_IP "192.168.109.12" //客戶端ip地址
#define CLI_PORT 7777 //客戶端端口號int main(int argc, const char *argv[])
{//1、創建用于通信的套接字文件描述符int cfd = socket(AF_INET, SOCK_STREAM, 0);if(cfd == -1){perror("socket error");return -1;}//2、給客戶端套接字綁定ip地址和端口號//2.1 填充地址信息結構體struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_addr.s_addr = inet_addr(CLI_IP);cin.sin_port = htons(CLI_PORT);//2.2 綁定if(bind(cfd, (struct sockaddr*)&cin, sizeof(cin))==-1){perror("bind error");return -1;}//3、連接服務器//3.1 組裝對端地址信息結構體struct sockaddr_in sin;sin.sin_family = AF_INET; //通信域sin.sin_addr.s_addr = inet_addr(SER_IP); //要連接的服務器ipsin.sin_port = htons(SER_PORT); //服務器的端口號//3.2 連接操作if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin))==-1){perror("connect error");return -1;}//4、數據通信char buf[128] = "";while(1){//從終端輸入要發送的消息fgets(buf, sizeof(buf), stdin);buf[strlen(buf)-1] = 0;//判斷輸入內容if(strcmp(buf, "quit")==0){break;}//將消息發送給服務器write(cfd, buf, strlen(buf));printf("發送成功\n");//接受服務器發來的消息bzero(buf, sizeof(buf));int res = read(cfd, buf, sizeof(buf));if(res == 0){printf("服務器已經下線\n");break;}printf("收到服務器消息:%s\n", buf);}//5、關閉套接字close(cfd);return 0;
}
運行
UDP服務器和客戶端通訊
服務器代碼
#include<myhead.h>
#define SER_IP "192.168.109.12"
#define SER_PORT 8888/*****************主程序*****************/
int main(int argc, const char *argv[])
{//1、創建一個用于通信的套接字文件描述符int sfd = socket(AF_INET, SOCK_DGRAM, 0);if(sfd == -1){perror("socket error");return -1;}//2、綁定ip地址和端口號(必須)//2.1 封裝結構體struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_addr.s_addr = inet_addr(SER_IP);sin.sin_port = htons(SER_PORT);//2.2 綁定if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin))==-1){perror("bind error");return -1;}//3、數據收發char buf[128] = ""; //用于接受對端消息//定義一個地址信息結構體的變量,用于接收對端地址struct sockaddr_in cin;socklen_t addrlen = sizeof(cin); //接受地址長度while(1){//清空容器bzero(buf, sizeof(buf));//從套接字文件描述符中讀取消息recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &addrlen);printf("[%s:%d] : %s\n",inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);//給消息加個笑臉還回去strcat(buf, ":D");//發送消息sendto(sfd, buf, strlen(buf), 0, (struct sockaddr*)&cin, sizeof(cin));printf("發送成功\n");}//4、關閉套接字close(sfd);return 0;
}
客戶端代碼
#include<myhead.h>#define SER_IP "192.168.109.12"
#define SER_PORT 8888/******************主程序******************/
int main(int argc, const char *argv[])
{//1、創建一個用于通信的套接字文件描述符int cfd = socket(AF_INET, SOCK_DGRAM, 0);if(cfd == -1){perror("socket error");return -1;}//2、綁定ip和端口號(可選)//3、數據收發char buf[128] = ""; //數據容器struct sockaddr_in sin; //目標地址sin.sin_family = AF_INET;sin.sin_port = htons(SER_PORT);sin.sin_addr.s_addr = inet_addr(SER_IP);socklen_t addrlen = sizeof(sin);while(1){//清空容器bzero(buf, sizeof(buf));fgets(buf, sizeof(buf), stdin); //從終端獲取數據buf[strlen(buf)-1] = 0;if(strcmp(buf,"quit")==0){break;}//將數據發送給服務器sendto(cfd, buf, strlen(buf), 0, (struct sockaddr*)&sin, sizeof(sin));printf("發送成功\n");//接收服務器發來的消息bzero(buf, sizeof(buf));//recvfrom(cfd, buf, sizeof(buf), 0, (struct socket*)&sin, &addrlen);//recvfrom(cfd, buf, sizeof(buf), 0, NULL,NULL);read(cfd, buf, sizeof(buf));printf("收到服務器消息為:%s\n", buf);}//4、關閉套接字close(cfd);return 0;
}
運行情況
牛客