關於socket編程,以下文章寫得比較好:http://www.cnblogs.com/xudong-bupt/archive/2013/12/29/3483059.html
1. accept()函數,如果客戶端一直沒有連接,則服務端阻塞在accept()函數處。
以下是client代碼
//============================================================================ // Name : client.cpp // Author : yjzhuang // Version : // Copyright : yjzhuang@corp.netease.com // Description : Hello World in C++, Ansi-style //============================================================================ #include <iostream> #include <sys/select.h> #include <sys/socket.h> #include <unistd.h> #include <pthread.h> #include <stdio.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string> #include <string.h> using namespace std; #define SERVER_IP "127.0.0.1" #define SERVER_PORT 9090 #define BUFSIZE 1024 int getSocket(){ int fd =socket( AF_INET, SOCK_STREAM, 0 ); cout<<"fd="<<fd<<endl; if(-1 == fd){ cout<<"Error, fd is -1"<<endl; } return fd; } /** * 連接到server端,如果成功,返回fd,如果失敗返回-1 */ int connectServer(){ int fd = getSocket(); cout<<"fd= "<<fd<<endl; if(-1 == fd){ cout<<"Error, connectServer() quit"<<endl; return -1; } struct sockaddr_in remote_addr; //服務器端網絡地址結構體 memset(&remote_addr,0,sizeof(remote_addr)); //數據初始化--清零 remote_addr.sin_family=AF_INET; //設置為IP通信 remote_addr.sin_addr.s_addr=inet_addr(SERVER_IP);//服務器IP地址 remote_addr.sin_port=htons(SERVER_PORT); //服務器端口號 int con_result = connect(fd, (struct sockaddr*) &remote_addr, sizeof(struct sockaddr)); if(con_result < 0){ cout<<"Connect Error!"<<endl; return -1; } cout<<"con_result="<<con_result<<endl; return fd; } /** *** 連接到server端,並且不斷往server端發送心跳數據 */ void* heartBeat(void* arg){ cout<<"Heart bead started!"<<endl; int fd = connectServer(); if(fd<0){ cout<<"Heart bead quit!"<<endl; return 0; } char buf[BUFSIZE]; //數據傳送的緩沖區 string value = "This is heart beat msg!"; strcpy(buf, value.c_str()); while(true){ cout<<"to write data"<<endl; cout<<"buf="<<buf<<", len="<<strlen(buf)<<endl; int write_num = write(fd, buf, strlen(buf)); cout<<"write_num="<<write_num<<endl; sleep(2); } cout<<"Heart bead finished!"<<endl; return 0; } /** *** 創建一個新線程,在新線程里調用heartBeat()函數 */ void threadCall(){ pthread_t thread; pthread_create(&thread,NULL,heartBeat,NULL); pthread_detach(thread); } int main() { cout << "main started" << endl; // prints Hello World!!! threadCall(); sleep(10000000); cout<<"main finished"<<endl; return 0; }
以下是server代碼
/* * server.cpp * * Created on: 2014年11月14日 * Author: yjzhuang */ #include <iostream> #include <sys/select.h> #include <sys/socket.h> #include <stdio.h> #include <unistd.h> #include <pthread.h> #include <stdio.h> #include <sys/types.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string> #include <string.h> using namespace std; #define SERVER_IP "127.0.0.1" #define SERVER_PORT 9090 #define BUFSIZE 1024 int getSocket(){ int fd =socket( AF_INET, SOCK_STREAM, 0 ); if(-1 == fd){ cout<<"Error, fd is -1"<<endl; } return fd; } int main(){ int fd = getSocket(); if(fd<0){ cout<<"Error in main(), fd<0"<<endl; } cout<<"fd="<<fd<<endl; //----為服務器主線程綁定ip和port------------------------------ struct sockaddr_in local_addr; //服務器端網絡地址結構體 memset(&local_addr,0,sizeof(local_addr)); //數據初始化--清零 local_addr.sin_family=AF_INET; //設置為IP通信 local_addr.sin_addr.s_addr=inet_addr(SERVER_IP);//服務器IP地址 local_addr.sin_port=htons(SERVER_PORT); //服務器端口號 int bind_result = bind(fd, (struct sockaddr*) &local_addr, sizeof(struct sockaddr)); if(bind_result < 0){ cout<<"Bind Error in main()"<<endl; return -1; } cout<<"bind_result="<<bind_result<<endl; //--------------------------------------------- listen(fd, 10); struct sockaddr_in remote_addr; int sin_size=sizeof(struct sockaddr_in); cout<<"before accept"<<endl; int new_fd = accept(fd, (struct sockaddr*) &remote_addr, (socklen_t*)&sin_size); cout<<"after accept"<<endl; if(new_fd < 0){ cout<<"Accept error in main()"<<endl; return -1; } cout<<"new_fd accepted is "<<new_fd<<endl; char buffer[BUFSIZE]; while(true){ cout<<"wait to read data..."<<endl; int len = read(new_fd, buffer, BUFSIZE); if(len == 0 ){ cout<<"Read from socket finished"<<endl; return 0; }else if(len < 0){ cout<<"Read from socket error"<<endl; return -1; } cout<<"Accept data:"<<buffer<<endl; sleep(10); } }
