通過上篇的講解,我們可以寫一個簡單的服務端、客戶端:
這裏仍有一些可圈點之處:
- INADDR_ANY,轉換過來就是0.0.0.0,是指本機所有ip,比如本機有多個網卡多個ip,只需綁定某個ip的地址,
只能監聽某個網卡過來的消息,這裏INADDR_ANY,監聽所有網卡的消息。 - inet_addr()將一個字符串類型的ip地址比如“192.168.0.100”轉化爲uint32_t數字格式,因爲網絡傳輸地址用的是uint32_t格式
- socket默認是阻塞的,阻塞的地方有:連接、收、發,其中連接有個系統超時時間,這個時間通常會很長,如果是我們一次發送大量的連接請求,一個阻塞後,後續的就一直等待,顯然是不合理的,所以我們一般會修改這個超時連接時間;對於收、發(即讀、寫),若是沒有數據到來則會一直阻塞,根據需求有時需要我們做一個非阻塞處理,在一定時間沒有數據到來時仍會返回。關於阻塞、非阻塞下篇講解。
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#define PORT 10102
int main()
{
int sockfd;
int client_fd;
//socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if( sockfd < 0 )
{
perror("socket error!");
return -1;
}
//bind
struct sockaddr_in client_addr, server_addr;
memset(&server_addr, 0x00, sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET; //協議
server_addr.sin_addr.s_addr=INADDR_ANY; //服務器地址--允許鏈接到本地任何地址
server_addr.sin_port=htons(PORT);
if(bind(sockfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) < 0)
{
perror("bind error!");
return -1;
}
//listen
listen(sockfd, 5); //5也是系統的默認值
printf("start listen......\n");
//accept 接收客戶端收鏈接
int size = sizeof(struct sockaddr_in);
if( (client_fd = accept(sockfd, (struct sockaddr *)&client_addr, &size)) < 0)
{
perror("accept error!");
return -1;
}
printf("accept client %s\n",inet_ntoa(client_addr.sin_addr));
send(client_fd, "welcome\n", 8, 0);
//recv/send
int n;
char buf[1024]={0};
while((n = recv(client_fd, buf, 1024, 0)) > 0)
{
buf[n] = '\0';
printf("%s\n", buf);
if(send(client_fd, buf, n, 0) < 0)
{
perror("error send!");
return -1;
}
}
close(client_fd);
close(sockfd);
return 0;
}
簡單的客戶端
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#define PORT 10102
int main()
{
int sockfd;
int client_fd;
//socket
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if( sockfd < 0 )
{
perror("socket error!");
return -1;
}
struct sockaddr_in server_addr;
memset(&server_addr, 0x00, sizeof(struct sockaddr_in));
server_addr.sin_family=AF_INET; //協議
server_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); //服務器地址
server_addr.sin_port=htons(PORT);
//connect
if(connect(sockfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) < 0)
{
perror("connect error!");
return -1;
}
//recv/send
char buf[1024]={0};
printf("connected to server\n");
recv(sockfd, buf, 1024, 0);
printf("%s\n",buf);
int n;
while(1)
{
memset(buf, 0x00, sizeof(buf));
printf("Enter string to send:");
scanf("%s",buf);
if(strncmp(buf,"quit", 4) == 0)
break;
n = send(sockfd, buf, strlen(buf), 0);
n = recv(sockfd, buf, 1024,0);
buf[n]='\0';
printf("recv:[%s]\n", buf);
}
close(sockfd);
return 0;
}