代码
server.c
//server.c
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
/* socket
* bind
* sendto/recvfrom
*/
#define SERVER_PORT 8888
#define BACKLOG 10
int main(int argc, char** argv)
{
int iSocketServer;
struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;
int iSocketClient;
int iRet;
int iAddrLen;
int iRecvLen;
unsigned char ucRecvBuf[1000];
int iClientNum = -1;
iSocketServer = socket(AF_INET, SOCK_DGRAM, 0);
if (iSocketServer == -1)
{
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 (iRet == -1)
{
printf("bind error\n");
return -1;
}
while (1)
{
iAddrLen = sizeof(struct sockaddr);
/*接收客户端发来的数据并显示*/
#if 0
iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 999, 0,
(struct sockaddr *)&tSocketClientAddr, &iAddrLen);
if (iRecvLen > 0)
{
ucRecvBuf[iRecvLen] = '\0';
printf("Get Msg from %s : %s", inet_ntoa(tSocketClientAddr.sin_addr), ucRecvBuf);
}
#else
iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 999, 0,
NULL, NULL);
if (iRecvLen > 0)
{
ucRecvBuf[iRecvLen] = '\0';
printf("Get Msg : %s", ucRecvBuf);
}
#endif
}
close(iSocketServer);
return 0;
}
client.c
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
/*
socket
connect
send/recv
*/
#define SERVER_PORT 8888
int main(int argc, char** argv)
{
int iSocketClient;
struct sockaddr_in tSocketServerAddr;
struct sockaddr_in tSocketClientAddr;
int iRet;
unsigned char ucSendBuf[1000];
int iSendLen;
if (argc != 2)
{
printf("Usage: %s <server_ip>\n", argv[0]);
return -1;
}
iSocketClient = socket(AF_INET, SOCK_DGRAM, 0);
if (iSocketClient == -1)
{
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;
if (0 == inet_aton(argv[1],&tSocketServerAddr.sin_addr))
{
printf("invalid server ip\n");
return -1;
}
memset(tSocketServerAddr.sin_zero, 0, 8);
#if 0
/*并不会真正连接,只是把ip以及端口信息与文件句柄连接在一起*/
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;
}
}
}
#else
while(1)
{
if (fgets(ucSendBuf, 999, stdin))
{
iSendLen = sendto(iSocketClient, ucSendBuf, strlen(ucSendBuf), 0,
(const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
if (iSendLen <= 0)
{
close(iSocketClient);
return -1;
}
}
}
#endif
return 0;
}
Note
- 创建socket时传入SOCK_DGRAM,表示UDP
- server端
对于TCP:server中需要使用listen和accept,client使用connect提前建立连接,然后采用send/recv收发数据
对于UDP:server使用recvfrom(),多了struct sockaddr *src_addr, socklen_t *addrlen两个参数,可传可不传,有以下两种情况:
#if 0 //传入
iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 999, 0,
(struct sockaddr *)&tSocketClientAddr, &iAddrLen);
if (iRecvLen > 0)
{
ucRecvBuf[iRecvLen] = '\0';
printf("Get Msg from %s : %s", inet_ntoa(tSocketClientAddr.sin_addr), ucRecvBuf);
}
#else //不传入
iRecvLen = recvfrom(iSocketServer, ucRecvBuf, 999, 0,
NULL, NULL);
if (iRecvLen > 0)
{
ucRecvBuf[iRecvLen] = '\0';
printf("Get Msg : %s", ucRecvBuf);
}
#endif
传入时可以知道信息来自于哪个客户端,不传入表示不关心信息来自于哪里。
3. client端
有以下两种情况,可以使用connect+send或只使用sendto函数
#if 0 //connect() + send()
/*并不会真正连接,只是把ip以及端口信息与文件句柄连接在一起*/
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;
}
}
}
#else //只使用sendto()函数
while(1)
{
if (fgets(ucSendBuf, 999, stdin))
{
iSendLen = sendto(iSocketClient, ucSendBuf, strlen(ucSendBuf), 0,
(const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr));
if (iSendLen <= 0)
{
close(iSocketClient);
return -1;
}
}
}
#endif