Linux下socket通信示例
程序员文章站
2022-06-29 22:49:18
...
服务端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;
}