1、背景
工作中经常有创建TCP和UDP客户端程序的时候,因此在将创建客户端的TCP和UDP的代码记录一下。
- socket创建
static int OpenSocket(char *svrIP, uint16_t svrPort, int mode)
{
int sockfd = -1;
int transport; // 默认使用UDP
struct sockaddr_in addr = {0, };
if (!svrIP)
{
GB_PrintError("svrIP is invalid.\n");
return -1;
}
transport = mode?SOCK_STREAM:SOCK_DGRAM;
sockfd = socket(AF_INET, transport, 0);
if (sockfd < 0)
{
GB_PrintError("create sock failed.\n");
return -1;
}
int opt = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0)
{
close(sockfd);
GB_PrintError("SOL_SOCKET SO_REUSEADDR failed.\n");
return -1;
}
// 如果是TCP 需要连接服务器
if (mode)
{
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = htons(svrPort);
addr.sin_addr.s_addr = inet_addr(svrIP);
if (connect(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0)
{
close(sockfd);
GB_PrintError("connet svr failed. stream svrip:%s, stream svrPort:%d. error code:%d\n", svrIP, svrPort, errno);
return -1;
}
}
return sockfd;
}
- 数据发送
static int sendStreamData(PreviewParam_t *handle, char *streamData, int streamLen, int mode)
{
int w = 0;
struct sockaddr_in addr = {0, };
if (!handle || !streamData || streamLen<= 0 || handle->scokfd < 0)
{
GB_PrintError("handle error.\n");
return -1;
}
// 如果是TCP方式
if (mode)
{
w = send(handle->scokfd, streamData, streamLen, 0);
}
else
{
addr.sin_family = AF_INET;
addr.sin_port = htons(handle->svrPort);
addr.sin_addr.s_addr = inet_addr(handle->svrIP);
w = sendto(handle->scokfd, streamData, streamLen, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr));
}
return w;
}
- 创建TCP服务端程序:
static int CreateTcpServer(uint16_t port)
{
int sockfd = -1;
struct sockaddr_in serveraddr = {0, };
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{
return -1;
}
int opt = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0)
{
close(sockfd);
return -1;
}
bzero((char *) &serveraddr, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port = htons(port);
if (bind(sockfd, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
{
close(sockfd);
return -1;
}
if (listen(sockfd, 5) < 0) /* allow 5 requests to queue up */
{
close(sockfd);
return -1;
}
return sockfd;
}
- 保存监听的句柄
int StreamServerProcess(void)
{
int socket = -1;
int clientLen = 0;
struct sockaddr_in clientAddr;
StreamSvrHandle_t *pStreamHanle = NULL;
pStreamHanle = GetStreamSvrHandle();
if (!pStreamHanle)
{
return -1;
}
if (pStreamHanle->svrSocket == -1)
{
pStreamHanle->svrSocket = CreateTcpServer(STREAM_SERVER_PORT);
}
clientLen = sizeof(clientAddr);
socket = accept(pStreamHanle->svrSocket, (struct sockaddr *) &clientAddr, &clientLen);
if (socket < 0)
{
close(pStreamHanle->svrSocket);
pStreamHanle->svrSocket = -1;
return -1;
}
else
{
if (AddStreamHandle(socket, &clientAddr))
{
return -1;
}
}
return 0;
}
参考资料:
网络基础–TCP/IP网络基础