Socket 编程
服务器端代码
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>
using namespace std;
#define ll long long
#define loop(i,start,end) for(int i=start;i<=end;++i)
/*bool checkIfFileExsit(char *FILENAME){
fstream _file;
_file.open(FILENAME,ios::in);
return (_file?0:1);
}*/
void SaveData(char *buffer){
char FileName[] = "Datalog.txt";
ofstream srcFile;
freopen(FileName, "a", stdout); //以文本模式打开in.txt备读
time_t current_time;
current_time = time(NULL);
int len = strlen(buffer);
cout << "\n<DataLog:" << (int)current_time << ">:"<< endl;
loop(i,0,len-1) cout <<buffer[i];
fclose(stdout);
}
int main(int argc, char *argv[]){
printf("INFO::Starting server\n");
if (argc != 2){
printf("ERROR::Using:./server port\nExample:./server 5005\n\n");
return -1;
}
// 第1步:创建服务端的socket。
int listenfd; // socket 就是一个数字罢了
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket");
return -1;
}
printf("INFO::Building Socket Successfully\n");
// 第2步:把服务端用于通信的地址和端口绑定到socket上。
struct sockaddr_in servaddr; // 服务端地址信息的数据结构。
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET; // 协议族,在socket编程中只能是AF_INET。
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 任意ip地址。
//servaddr.sin_addr.s_addr = inet_addr("192.168.190.134"); // 指定ip地址。
servaddr.sin_port = htons(atoi(argv[1])); // 指定通信端口。
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0){
perror("bind");
close(listenfd);
return -1;
}//这里绑定一波通信端口
printf("INFO::Bind Socket To Port Successfully\n");
// 第3步:把socket设置为监听模式。
if (listen(listenfd, 5) != 0){
perror("listen");
close(listenfd);
return -1;
}
// 第4步:接受客户端的连接。
int clientfd; // 客户端的socket。
int socklen = sizeof(struct sockaddr_in); // struct sockaddr_in的大小
struct sockaddr_in clientaddr; // 客户端的地址信息。
printf("INFO::Load Socket On Successfully || IP:%s\nwaiting for requests...\n", inet_ntoa(servaddr.sin_addr));
clientfd = accept(listenfd, (struct sockaddr *)&clientaddr, (socklen_t *)&socklen);
printf("INFO::客户端(%s)已连接。\n", inet_ntoa(clientaddr.sin_addr));
// 第5步:与客户端通信,接收客户端发过来的报文后,回复ok。
char buffer[1024];
while (1){
int iret;
memset(buffer, 0, sizeof(buffer));
if ((iret = recv(clientfd, buffer, sizeof(buffer), 0)) <= 0){ // 接收客户端的请求报文。
printf("iret=%d\n", iret);
break;
}
printf("Input Message:%s\n", buffer);
SaveData(buffer);
sprintf(buffer,"Finish Saving");
if ((iret = send(clientfd, buffer, strlen(buffer), 0)) <= 0){ // 向客户端发送响应结果。
perror("send");
break;
}
printf("Output Message:%s\n", buffer);
}
// 第6步:关闭socket,释放资源。
close(listenfd);
close(clientfd);
}
客户端代码
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main(int argc,char *argv[]){
if (argc!=3){
printf("Using:./client ip port\nExample:./client 127.0.0.1 5005\n\n"); return -1;
}
// 第1步:创建客户端的socket。
int sockfd;
if ( (sockfd = socket(AF_INET,SOCK_STREAM,0))==-1) {
perror("socket"); return -1;
}
// 第2步:向服务器发起连接请求。
struct hostent* h;
if ( (h = gethostbyname(argv[1])) == 0 ){ // 指定服务端的ip地址。
printf("gethostbyname failed.\n");
close(sockfd);
return -1;
}
struct sockaddr_in servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(atoi(argv[2])); // 指定服务端的通信端口。
memcpy(&servaddr.sin_addr,h->h_addr,h->h_length);
if (connect(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr)) != 0) { // 向服务端发起连接清求。
perror("connect");
close(sockfd);
return -1;
}
char buffer[1024];
// 第3步:与服务端通信,发送一个报文后等待回复,然后再发下一个报文。
for (int ii=0;ii<20;ii++){
sleep(0.1);
int iret;
memset(buffer,0,sizeof(buffer));
//sprintf(buffer,"这是第%d个message: 编号%03d。",ii+1,ii+1);
for(int j=0;j<=ii;++j) buffer[j]=j%3?'k':'a';
printf("%s\n", buffer);
if ( (iret=send(sockfd,buffer,strlen(buffer),0))<=0){ // 向服务端发送请求报文。
perror("send");
break;
}
printf("发送:%s\n",buffer);
memset(buffer,0,sizeof(buffer));
if ( (iret=recv(sockfd,buffer,sizeof(buffer),0))<=0){ // 接收服务端的回应报文。
printf("iret=%d\n",iret);
break;
}
printf("接收:%s\n",buffer);
}
// 第4步:关闭socket,释放资源。
close(sockfd);
}
服务器端重启动代码
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define ll long long
#define loop(i,start,end) for(int i=start;i<=end;++i)
ll transform(char *argv, int length){
ll x = 0;int p=0;
while(p<length&&(argv[p]<'0'||argv[p]>'9')){p++;};
while(p<length&&argv[p]>='0'&&argv[p]<='9'){x=(x<<1)+(x<<3)+argv[p]-'0';p++;}
return x;
}
int main(int argc, char *argv[]){
printf("%d %s\n",argc, argv[1]);
int T = transform(argv[1], strlen(argv[1]));
printf("%d\n",T);
while(T--){
int x = system("./server 5005");
if(x == 0)
printf("SUC!\n");
else
printf("ERROR HAPPEND\n");
sleep(2);
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 AndrewLee!