一、概述
利用C寫一個客戶端服務器模式的簡單的Socket網絡通訊服務,此服務特別簡單:只需要一個Server對應一個Client的聊天,不支持多個Client和Server聊天,聊天模式也比較簡單,就是發什么會回復什么。
1.Server.cpp的創建步驟
a.創建socket
b.設置參數setsockopt
c.綁定bind
d.監聽listen
e.接收客戶端發送過來的消息accept
f.給客戶端回復消息send
g.關閉鏈接 close
2.Client端的創建步驟
a.創建socket
b.連接服務端 connect
c.給服務端發送消息 send
d.接收來自服務端的消息recv
f.關閉socket
3.執行成功后手動編譯或者放工具編輯都可。在client終端輸入要發送的內容,在終端就會顯示發送內容以及服務端回復的內容。
二、代碼示例
1.client代碼
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#define MESSAGE_LEN 1024
#define PORT 8888
using namespace std;
int main(int argc, char const *argv[])
{
/* code */
//創建socket
int socket_fd;
int ret=-1;
struct sockaddr_in serveraddr;
char sendbuf[MESSAGE_LEN] = {0,};
char recvbuf[MESSAGE_LEN] = {0,};
socket_fd = socket(AF_INET,SOCK_STREAM,0);
if(socket_fd==-1){
cout << ""<<endl;
exit(-1);
}
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = PORT;
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = connect(socket_fd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
if(ret<0){
cout<<"Failed to connect server!"<<endl;
exit(-1);
}
while(1){
memset(sendbuf,0,MESSAGE_LEN);
gets(sendbuf);
ret = send(socket_fd,sendbuf,strlen(sendbuf),0);
if(ret<=0){
cout<<"Failed tosend data!"<<endl;
break;
}
if(strcmp(sendbuf,"quit")==0){
break;
}
ret = recv(socket_fd,recvbuf,MESSAGE_LEN,0);
recvbuf[ret] = '\0';
cout << "recv:"<<recvbuf<<endl
;
}
close(socket_fd);
return 0;
}
2.server代碼
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#define PORT 8888
#define MESSAGE_LEN 1024
int main(int argc, char const *argv[])
{
int socket_fd,accept_fd;
int on= 1;
int ret =-1;
int backlog = 10;
struct sockaddr_in localaddr ,remoteaddr;
socket_fd = socket(AF_INET,SOCK_STREAM,0);
char in_buff[MESSAGE_LEN] = {0};
//如果socket創建失敗就退出
if(socket_fd==-1){
std::cout<<"Failed to create socket!"<<std::endl;
exit(-1);
}
ret = setsockopt(
socket_fd,
SOL_SOCKET,
SO_REUSEADDR,
&on,
sizeof(on));
if(ret==-1){
std::cout<<"Failed 通setsocket options!"<<std::endl;
exit(-1);
}
localaddr.sin_family=AF_INET;
localaddr.sin_port = PORT;
localaddr.sin_addr.s_addr = INADDR_ANY;
bzero(&(localaddr.sin_zero),8);
ret = bind(socket_fd,
(struct sockaddr*)&localaddr,sizeof(struct sockaddr));
if(ret ==-1){
std::cout<< "Failed to bind addr!"<<std::endl;
exit(-1);
}
ret = listen(socket_fd,backlog);
if(ret==-1){
std::cout<< "Failed to bind listen socket!"<<std::endl;
exit(-1);
}
for(;;){
socklen_t addr_len = sizeof(struct sockaddr);
accept_fd = accept(socket_fd,(struct sockaddr*)&remoteaddr,&addr_len);
for(;;){
ret=recv(accept_fd,(void*)in_buff,MESSAGE_LEN,0);
if(ret==0){
break;
}
std::cout << "recv:"<< in_buff<<std::endl;
send(accept_fd,(void*)in_buff,MESSAGE_LEN,0);
}
close(accept_fd);
}
close(socket_fd);
return 0;
}
