1.需要先获得socket
fd = socket(AF_INET, SOCK_DGRAM, 0);
AF_INET代表使用IPV4协议族
SOCK_DGRAM代表TCP/IP连接
2.bind() 把获得的socket和要监听的ip端口绑定起来
3.listen()启动监测数据
4.accept()接受/建立一条连接 等待客户端连接
5.send() 发数据
recv() 收数据
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#include
#include
/* socket
* bind
* listen
* accept
* send/recv
*/
#define SERVER_PORT 7897
#define BACKLOG 10
int main(int argc, char **argv)
{
int iSocketServer;
int iSocketClient;
struct sockaddr_in tSocketServerAddr; //指定服务器绑定地址
struct sockaddr_in tSocketClientAddr; //保存客户端地址
int iRet;
int iAddrLen;
int iRecvLen;
unsigned char ucRecvBuf[1000];
int iClientNum = -1;
signal(SIGCHLD,SIG_IGN); //此函数用于处理僵尸进程
iSocketServer = socket(AF_INET, SOCK_STREAM, 0);//AF_INET IPV4连接 SOCK_STREAM启动TCP连接
if (-1 == iSocketServer)
{
printf("socket error!\n");
return -1;
}
tSocketServerAddr.sin_family = AF_INET; //一般设置为
tSocketServerAddr.sin_port = htons(SERVER_PORT); //将SERVER_PORT转化为网络字节序 host to net, short
tSocketServerAddr.sin_addr.s_addr = INADDR_ANY; //INADDR_ANY表示本机上所有IP
memset(tSocketServerAddr.sin_zero, 0, 8);
int opt = 1;
//使用setsockopt函数可以保证端口可被重复绑定
iRet = setsockopt(iSocketServer, SOL_SOCKET,SO_REUSEADDR,
(const void *)&opt, sizeof(opt) );
if (-1 == iRet)
{
printf("set sock option error!\n");
close(iSocketServer);
return -1;
}
iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr)); //绑定端口
if (-1 == iRet)
{
printf("bind error!\n");
close(iSocketServer);
return -1;
}
iRet = listen(iSocketServer, BACKLOG); //设置监听 BACKLOG代表同时监听10路连接
if (-1 == iRet)
{
printf("listen error!\n");
return -1;
}
while (1)
{
iAddrLen = sizeof(struct sockaddr);
iSocketClient = accept(iSocketServer, (struct sockaddr *)&tSocketClientAddr, &iAddrLen); //等待连接 如果建立连接
if (-1 != iSocketClient)
{
iClientNum++;
printf("Get connect from client %d : %s\n", iClientNum, inet_ntoa(tSocketClientAddr.sin_addr));
if (!fork()) //fork创建子进程 返回值为0的是子进程
{
/* 子进程中处理客户端数据 */
while (1)
{
/* 接收客户端发来的数据并显示出来 */
iRecvLen = recv(iSocketClient, ucRecvBuf, 999, 0);
if (iRecvLen <= 0)
{
close(iSocketClient); //关闭连接
return -1;
}
else
{
ucRecvBuf[iRecvLen] = '\0';
printf("Get Msg From Client %d: %s\n", iClientNum, ucRecvBuf);
send(iSocketClient, "ok", 2, 0);//打印的同时发送一条数据给连接的客户端
}
}
}
}
}
close(iSocketServer);
return 0;
}
服务器端每收到一个客户端连接都会使用fork()创建一个子进程。每个子进程分别处理自己的数据请求。
关于fork()函数的详解可以看看这篇文章https://blog.csdn.net/weixin_42736024/article/details/81412962
1、获取socket
iSocketClient = socket(AF_INET, SOCK_STREAM, 0);
AF_INET代表使用IPV4协议族
SOCK_STREAM代表tcp/ip连接
2、将获取的ip 使用inet_aton()转化为能用的ip
3、将socket链接到指定端口
connect(iSocketClient, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
3、send(iSocketClient, ucSendBuf, strlen(ucSendBuf), 0); 发送数据
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#include
/* socket
* connect
* send/recv
*/
#define SERVER_PORT 8888
int main(int argc, char **argv)
{
int iSocketClient;
struct sockaddr_in tSocketServerAddr;
int iRet;
unsigned char ucSendBuf[1000];
int iSendLen;
if (argc != 2)
{
printf("Usage:\n");
printf("%s \n", argv[0]);
return -1;
}
iSocketClient = socket(AF_INET, SOCK_STREAM, 0); //获得socket
//设置需要连接的ip端口
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT); /*将端口转化成网络字节序 */
//tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
if (0 == inet_aton(argv[1], &tSocketServerAddr.sin_addr)) //将命令行读入的字符串ip转化成能用的ip
{
printf("invalid server_ip\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
iRet = connect(iSocketClient, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));//建立连接
if (-1 == iRet)
{
printf("connect error!\n");
return -1;
}
while (1)
{
if (fgets(ucSendBuf, 999, stdin))//从标准输入获得数据 以回车为结尾
{
iSendLen = send(iSocketClient, ucSendBuf, strlen(ucSendBuf), 0);
if (iSendLen <= 0)
{
close(iSocketClient);
return -1;
}
}
}
return 0;
}
fd=socket()
bind()绑定IP端口
revfrom()接收数据
sendto()发送数据
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#include
#include
/* socket
* bind
* sendto/recvfrom
*/
#define SERVER_PORT 8888
int main(int argc, char **argv)
{
int iSocketServer;
int iSocketClient;
struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;
int iRet;
int iAddrLen;
int iRecvLen;
unsigned char ucRecvBuf[1000];
int iClientNum = -1;
iSocketServer = socket(AF_INET, SOCK_DGRAM, 0); //SOCK_DGRAM代表UDP连接
if (-1 == iSocketServer)
{
printf("socket error!\n");
return -1;
}
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT); /* host to net, short */
tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
memset(tSocketServerAddr.sin_zero, 0, 8);
iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
if (-1 == iRet)
{
printf("bind error!\n");
return -1;
}
while (1)
{
iAddrLen = sizeof(struct sockaddr);
iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
if (iRecvLen > 0)
{
ucRecvBuf[iRecvLen] = '\0';
printf("Get Msg From %s : %s\n", inet_ntoa(tSocketClientAddr.sin_addr), ucRecvBuf);
}
}
close(iSocketServer);
return 0;
}
fd=socket
connect() UDP连接的connect实际上不会进行连接只会绑定IP端口
sendto()或者send()发送数据
recvform() 或者recv()接收数据
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#include
/* socket
* connect
* send/recv
*/
#define SERVER_PORT 8888
int main(int argc, char **argv)
{
int iSocketClient;
struct sockaddr_in tSocketServerAddr;
int iRet;
unsigned char ucSendBuf[1000];
int iSendLen;
if (argc != 2)
{
printf("Usage:\n");
printf("%s \n", argv[0]);
return -1;
}
iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT); /* host to net, short */
//tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
if (0 == inet_aton(argv[1], &tSocketServerAddr.sin_addr))
{
printf("invalid server_ip\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
iRet = connect(iSocketClient, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
if (-1 == iRet)
{
printf("connect error!\n");
return -1;
}
while (1)
{
if (fgets(ucSendBuf, 999, stdin))
{
iSendLen = send(iSocketClient, ucSendBuf, strlen(ucSendBuf), 0);
if (iSendLen <= 0)
{
close(iSocketClient);
return -1;
}
}
}
return 0;
}
1)服务器
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#include
#include
#include
/* socket
* bind
* sendto/recvfrom
*/
#define SERVER_PORT 5678
static pthread_t g_tSendTreadID;
static pthread_t g_tRecvTreadID;
static pthread_mutex_t g_tSendMutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t g_tSendConVar = PTHREAD_COND_INITIALIZER;
static struct sockaddr_in tSocketServerAddr;
static struct sockaddr_in tSocketClientAddr;
int iSocketServer;
int iSocketClient;
static void *SendTreadFunction(void *pVoid)
{
int iAddrLen = sizeof(struct sockaddr);
while(1)
{
/* 平时休眠 */
pthread_mutex_lock(&g_tSendMutex);
pthread_cond_wait(&g_tSendConVar, &g_tSendMutex);
pthread_mutex_unlock(&g_tSendMutex);
sendto(iSocketServer, "ok\n", 2, 0,(const struct sockaddr *)&tSocketClientAddr, iAddrLen);
}
}
int main(int argc, char **argv)
{
int iRet;
int iAddrLen;
int iRecvLen;
unsigned char ucRecvBuf[1000];
int iClientNum = -1;
iSocketServer = socket(AF_INET, SOCK_DGRAM, 0); //获得socket
if (-1 == iSocketServer)
{
printf("socket error!\n");
return -1;
}
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT); /* host to net, short */
tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
memset(tSocketServerAddr.sin_zero, 0, 8);
int opt = 1;
iRet = setsockopt(iSocketServer, SOL_SOCKET,SO_REUSEADDR,
(const void *)&opt, sizeof(opt) ); //使用此函数可以保证端口可被重复绑定
if (-1 == iRet)
{
printf("set sock option error!\n");
close(iSocketServer);
return -1;
}
iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr)); //将socket与ip端口绑定在一起
if (-1 == iRet)
{
printf("bind error!\n");
close(iSocketServer);
return -1;
}
/* 创建netprint发送线程: 它用来发送打印信息给客户端 */
pthread_create(&g_tSendTreadID, NULL, SendTreadFunction, NULL);
//pthread_create(&g_tRecvTreadID, NULL, RecvTreadFunction, NULL);
while (1)
{
iAddrLen = sizeof(struct sockaddr);
iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
if (iRecvLen > 0)
{
ucRecvBuf[iRecvLen] = '\0';
printf("Get Msg From %s : %s\n", inet_ntoa(tSocketClientAddr.sin_addr), ucRecvBuf);
//唤醒发送线程
pthread_mutex_lock(&g_tSendMutex);
pthread_cond_signal(&g_tSendConVar);
pthread_mutex_unlock(&g_tSendMutex);
}
}
close(iSocketServer);
return 0;
}
2)客户端
#include /* See NOTES */
#include
#include
#include
#include
#include
#include
#include
/* socket
* connect
* send/recv
*/
#define SERVER_PORT 5678
int main(int argc, char **argv)
{
int iSocketClient;
struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;
int iRet;
int iRecvLen;
unsigned char ucSendBuf[1000];
unsigned char ucRecvBuf[1000];
int iSendLen;
int iAddrLen;
if (argc != 2)
{
printf("Usage:\n");
printf("%s \n", argv[0]); //
return -1;
}
iSocketClient = socket(AF_INET, SOCK_DGRAM, 0); //申请socket
tSocketServerAddr.sin_family = AF_INET;
tSocketServerAddr.sin_port = htons(SERVER_PORT); /* host to net, short */
//tSocketServerAddr.sin_addr.s_addr = INADDR_ANY;
if (0 == inet_aton(argv[1], &tSocketServerAddr.sin_addr))//将输入的ip地址转化成网络字节序
{
printf("invalid server_ip\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
while (1)
{
if (fgets(ucSendBuf, 999, stdin))
{
iAddrLen = sizeof(struct sockaddr);
iSendLen = sendto(iSocketClient, ucSendBuf, strlen(ucSendBuf), 0,
(const struct sockaddr *)&tSocketServerAddr, iAddrLen);
if (iSendLen <= 0)
{
close(iSocketClient);
return -1;
}
}
iAddrLen = sizeof(struct sockaddr);
//收到来自 inet_ntoa(tSocketClientAddr.sin_addr) 地址的信息
iRecvLen = recvfrom(iSocketClient, ucRecvBuf, 999, 0, (struct sockaddr *)&tSocketClientAddr, &iAddrLen);
if (iRecvLen > 0)
{
printf("Get Msg From %s : %s\n", inet_ntoa(tSocketClientAddr.sin_addr), ucRecvBuf);
}
}
return 0;
}