服務端socket流程:socket() –> bind() –> listen() –> accept() –> 讀取、發送信息(recv,send等)
客戶端socket流程:socket() –> connect() –> 發送、讀取信息(send,recv等)
參考:Socket基本操作
最基礎版本
服務端監聽某個端口,客戶端連接之後發送數據——>客戶端斷開連接後,服務端也關閉了
服務端:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
const int Port = 8888;
int main(void){
int sock_fd;
struct sockaddr_in mysock;
sock_fd = socket(AF_INET,SOCK_STREAM,0);//初始化socket
memset(&mysock,0,sizeof(mysock));
//編輯地址信息
mysock.sin_family = AF_INET;
mysock.sin_port = htons(Port);
mysock.sin_addr.s_addr = INADDR_ANY;
bind(sock_fd,(struct sockaddr *)&mysock,sizeof(struct sockaddr));//綁定地址,然後監聽
if(listen(sock_fd,10) < -1){
printf("listen error.\n");
}
int sin_size = sizeof(struct sockaddr_in);
struct sockaddr_in client_addr;
int new_fd;
char buf[1024];
char sedbuf[1024] = "recv successfully.\n";
printf("listening...\n");
new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);//accpet
while(1){
int len = recv(new_fd,buf,sizeof(buf),0);
fputs(buf,stdout);
send(new_fd, sedbuf, sizeof(sedbuf), 0);
if(strcmp(buf,"exit\n") == 0){
break;
}
memset(buf,0,sizeof(buf));
}
close(new_fd);
close(sock_fd);
return 0;
客戶端:
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<string.h>
#include<errno.h>
const int Port = 8888;
int main(void){
int sock_fd;
char buf[1024], sendbuf[1024], recvbuf[1024];
struct sockaddr_in server_addr;
sock_fd = socket(AF_INET, SOCK_STREAM, 0);//初始化socket
if(sock_fd == -1){
printf("%s\n",strerror(errno));
return 0;
}
bzero(&server_addr, sizeof(server_addr));//編輯服務端地址信息
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(Port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
int tmp = connect(sock_fd, (struct sockaddr *)(&server_addr),
sizeof(struct sockaddr));//連接服務端socket
if(tmp == -1){
printf("%s\n",strerror(errno));
return 0;
}
while(1){
fgets(sendbuf, sizeof(sendbuf), stdin);
send(sock_fd, sendbuf, strlen(sendbuf), 0);
if(strcmp(sendbuf, "exit\n") == 0)
break;
recv(sock_fd, recvbuf, sizeof(recvbuf), 0);
fputs(recvbuf, stdout);
memset(sendbuf, 0, sizeof(sendbuf));
memset(recvbuf, 0, sizeof(recvbuf));
}
close(sock_fd);
return;
}
多客戶端與服務端通信
只需在服務端修改,增加多線程,就可以同時接收多個客戶端發送的信息了。
服務端:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <pthread.h>
const int Port = 8888;
pthread_mutex_t g_mutext;
struct pthread_data{
struct sockaddr_in client_addr;//客戶端的地址信息
int sock_fd;//與客戶端通信的Socket文件描述符
};
void serveForClient(void * arg);
int main(void){
int sock_fd;
struct sockaddr_in mysock;
struct pthread_data pdata;
pthread_t pt;
sock_fd = socket(AF_INET,SOCK_STREAM,0);//初始化socket
//編輯地址信息
memset(&mysock,0,sizeof(mysock));
mysock.sin_family = AF_INET;
mysock.sin_port = htons(Port);
mysock.sin_addr.s_addr = INADDR_ANY;
bind(sock_fd,(struct sockaddr *)&mysock,sizeof(struct sockaddr));//綁定地址,然後監聽
if(listen(sock_fd,10) < -1){
printf("listen error.\n");
}
int sin_size = sizeof(struct sockaddr_in);
struct sockaddr_in client_addr;
int new_fd;
printf("listening...\n");
while(1){
new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);//accpet
//將client信息和Socket文件描述符打包進結構體中,傳給線程
pdata.client_addr = client_addr;
pdata.sock_fd = new_fd;
pthread_create(&pt, NULL, serveForClient, (void *)&pdata);//新開一個線程,與這個連接進來的client通信
}
close(new_fd);
close(sock_fd);
return 0;
}
void serveForClient(void *arg){
struct pthread_data *pdata = (struct pthread_data*)arg;
int new_fd = pdata->sock_fd;
char recvbuf[1024];
char sendbuf[1024] = "recv successfully.\n";
while(1){
recv(new_fd,recvbuf,sizeof(recvbuf),0);
fputs(recvbuf,stdout);
strcpy(sendbuf, recvbuf);
send(new_fd, sendbuf, sizeof(sendbuf), 0);
if(strcmp(recvbuf,"exit\n") == 0){
break;
}
memset(recvbuf,0,sizeof(recvbuf));
}
return;
}