linux系统编程-SOCKET通信基础编程(0)-常用数据结构
linux系统编程-SOCKET通信基础编程(1)-TCP客户端创建
linux系统编程-SOCKET通信基础编程(2)-TCP服务端创建
1.服务端创建流程
1.1创建服务端scoket
socket 本身就时一个整型值,相当于一个文件描述符
int socket(int domain, int type, int protocol);
int server_sock = socket(AF_INET, SOCK_STREAM, 0);//注意这里使用的是 SOCK_STREAM 流套接口
1.2设置IP地址信息
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
1.3绑定IP地址信息
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
ret = bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
1.4开始监听是否有链接和设置监听链接数量
int listen(int sockfd, int backlog);
ret = listen(server_sock, 5);
1.5开始等地啊接收客户端链接请求
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &addrlen);
1.6向客户端发送消息
send(sockfd, buf, len, flags);
ret = send(client_sock, buf, strlen(buf), 0);
1.7接收客户端消息
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ret = recv(client_sock, buf, BUFLEN, 0);
1.8关闭socket
close(socket);
1.9完整例程
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#define SERVER_PORT 6666
#define BUFLEN 256
int setup_socket()
{
int ret = 0;
//1,创建SOCKET, 服务器的服务套接字
int server_sock = socket(AF_INET, SOCK_STREAM, 0);
if(server_sock < 0)
{
perror("socket");
goto SOCKET_ERR;
}
//2, 填充服务器的地址信息
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY;
//3,绑定
ret = bind(server_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
if(ret < 0)
{
perror("bind");
goto SOCKET_ERR;
}
//设置可以复用地址
int on = 1;
if(setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1){
perror("setsockopt");
goto SOCKET_ERR;
}
//4, 监听
ret = listen(server_sock, 5);
if(ret < 0)
{
perror("listen");
goto SOCKET_ERR;
}
return server_sock;
SOCKET_ERR:
return -1;
}
int main()
{
char buf[BUFLEN] = {0};
int client_sock = 0, ret = 0;
socklen_t addrlen=0;
int server_sock = setup_socket();
struct sockaddr_in client_addr;
bzero(&client_addr, sizeof(client_addr));
addrlen = sizeof(client_addr);
if(server_sock < 0)
{
perror("setup_socket");
goto SOCKET_ERR;
}
while(1)
{
//5, 接收连接
client_sock = accept(server_sock, (struct sockaddr *)&client_addr, &addrlen);
printf("accept connect form IP: %s, port:%d\n",(char *)inet_ntoa(client_addr.sin_addr.s_addr) , ntohl(client_addr.sin_port));
//6, 读数据
ret = recv(client_sock, buf, BUFLEN, 0);
if(ret < 0)
{
perror("recv");
goto SOCKET_ERR;
}
printf("recv cliet msg:%s\n", buf);
//7, 发数据
bzero(buf, BUFLEN);
strcpy(buf, "Hello World!\n");
ret = send(client_sock, buf, strlen(buf), 0);
//8,关闭连接
close(client_sock);
}
SOCKET_ERR:
return 0;
}
附加 设置地址复用
int on = 1;
if(setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
{
perror("setsockopt");
goto SOCKET_ERR;
}