tcp_socket.h:
#ifndef TCP_SCOKET_H
#define TCP_SCOKET_H
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAX_CONNECT_NUM 10
int tcp_init(const char* ip, int port);
int tcp_accept(int sfd);
int tcp_connect(const char* ip, int port);
int tcp_nonblocking_recv(int conn_sockfd,
void *rx_buf,
int buf_len,
int timeval_sec,
int timeval_usec);
int tcp_blocking_recv(int conn_sockfd, void *rx_buf, uint16_t buf_len);
int tcp_send(int conn_sockfd, uint8_t *tx_buf, uint16_t buf_len);
void tcp_close(int sockfd);
#endif
tcp_socket.c:
#include "tcp_socket.h"
int tcp_init(const char* ip, int port)
{
int optval = 1;
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0)
{
perror("socket");
return -1;
}
/* 解除端口占用 */
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0)
{
perror("setsockoptn");
return -1;
}
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(struct sockaddr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
if (NULL == ip)
{
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
}
else
{
server_addr.sin_addr.s_addr = inet_addr(ip);
}
if (bind(server_fd, (struct sockaddr*)&server_addr,sizeof(struct sockaddr)) < 0)
{
perror("bind");
close(server_fd);
return -1;
}
if(listen(server_fd, MAX_CONNECT_NUM) < 0)
{
perror("listen");
close(server_fd);
return -1;
}
return server_fd;
}
int tcp_accept(int server_fd)
{
struct sockaddr_in client_addr = {0};
int addrlen = sizeof(struct sockaddr);
int new_fd = accept(server_fd, (struct sockaddr*) &client_addr, &addrlen);
if(new_fd < 0)
{
perror("accept");
close(server_fd);
return -1;
}
return new_fd;
}
int tcp_connect(const char *ip, int port)
{
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0)
{
perror("socket");
return -1;
}
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(struct sockaddr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = inet_addr(ip);
if (connect(server_fd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) < 0)
{
perror("connect");
close(server_fd);
return -1;
}
return server_fd;
}
int tcp_nonblocking_recv(int conn_sockfd, void *rx_buf, int buf_len, int timeval_sec, int timeval_usec)
{
fd_set readset;
struct timeval timeout = {0, 0};
int maxfd = 0;
int fp0 = 0;
int recv_bytes = 0;
int ret = 0;
timeout.tv_sec = timeval_sec;
timeout.tv_usec = timeval_usec;
FD_ZERO(&readset);
FD_SET(conn_sockfd, &readset);
maxfd = conn_sockfd > fp0 ? (conn_sockfd+1) : (fp0+1);
ret = select(maxfd, &readset, NULL, NULL, &timeout);
if (ret > 0)
{
if (FD_ISSET(conn_sockfd, &readset))
{
if ((recv_bytes = recv(conn_sockfd, rx_buf, buf_len, MSG_DONTWAIT))== -1)
{
perror("recv");
return -1;
}
}
}
else
{
return -1;
}
return recv_bytes;
}
int tcp_blocking_recv(int conn_sockfd, void *rx_buf, uint16_t buf_len)
{
return recv(conn_sockfd, rx_buf, buf_len, 0);
}
int tcp_send(int conn_sockfd, uint8_t *tx_buf, uint16_t buf_len)
{
return send(conn_sockfd, tx_buf, buf_len, 0);
}
void tcp_close(int sockfd)
{
close(sockfd);
}
x下面測(cè)試代碼:
#include "tcp_socket.h"
int main(int argc, char **argv)
{
printf("==================tcp server==================n");
int server_fd = tcp_init(NULL, 4321);
if (server_fd < 0)
{
printf("tcp_init error!n");
exit(EXIT_FAILURE);
}
int client_fd = tcp_accept(server_fd);
if (client_fd < 0)
{
printf("tcp_accept error!n");
exit(EXIT_FAILURE);
}
while (1)
{
char buf[128] = {0};
int recv_len = tcp_blocking_recv(client_fd, buf, sizeof(buf));
if (recv_len <= 0)
{
printf("recv error!n");
tcp_close(client_fd);
tcp_close(server_fd);
exit(EXIT_FAILURE);
}
printf("recv : %sn", buf);
int send_len = tcp_send(client_fd, buf, strlen(buf));
if (send_len <= 0)
{
printf("send error!n");
tcp_close(client_fd);
tcp_close(server_fd);
exit(EXIT_FAILURE);
}
else
{
printf("send success! send: %s, send_len: %dn", buf, send_len);
}
}
tcp_close(server_fd);
return 0;
}
tcp_client.c:
#include "tcp_socket.h"
int main(int argc, char **argv)
{
printf("==================tcp cient==================n");
if (argc < 3)
{
printf("usage:./tcp_client ip portn");
exit(EXIT_FAILURE);
}
char ip_buf[32] = {0};
int port = 0;
memcpy(ip_buf, argv[1], strlen(argv[1]));
port = atoi(argv[2]);
int server_fd = tcp_connect(ip_buf, port);
if (server_fd < 0)
{
printf("tcp_connect error!n");
exit(EXIT_FAILURE);
}
while (1)
{
char buf[128] = {0};
if (scanf("%s", buf))
{
int send_len = tcp_send(server_fd, buf, strlen(buf));
if (send_len <= 0)
{
printf("tcp_send error!n");
tcp_close(server_fd);
exit(EXIT_FAILURE);
}
else
{
printf("send success! send: %s, send_len: %dn", buf, send_len);
}
bzero(buf, sizeof(buf));
int recv_len = tcp_blocking_recv(server_fd, buf, sizeof(buf));
if (recv_len <= 0)
{
printf("tcp_blocking_recv error!n");
tcp_close(server_fd);
exit(EXIT_FAILURE);
}
printf("recv : %sn", buf);
}
}
return 0;
}
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。
舉報(bào)投訴
-
TCP
+關(guān)注
關(guān)注
8文章
1347瀏覽量
78934 -
C代碼
+關(guān)注
關(guān)注
1文章
89瀏覽量
14270
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
基于MCS-51單片機(jī)的點(diǎn)陣屏實(shí)現(xiàn)禮花功能(含源代碼)
電子發(fā)燒友網(wǎng)原創(chuàng):本文是基于MCS-51單片機(jī)的點(diǎn)陣屏實(shí)現(xiàn)禮花功能(含源代碼和功能實(shí)現(xiàn)圖)
發(fā)表于 08-08 14:07
?7334次閱讀
TCP 28J60模塊代碼分享!
C51代碼,控制28J60模塊實(shí)現(xiàn)了部分網(wǎng)絡(luò)傳輸功能。有點(diǎn)亂。TCP_28J60.zip (430.77 KB )
發(fā)表于 09-18 21:34
怎么使具體實(shí)現(xiàn)代碼不可見(jiàn)實(shí)現(xiàn)函數(shù)的封裝?
如何實(shí)現(xiàn)函數(shù)的封裝,即能讓別人調(diào)用,但是看不到具體的實(shí)現(xiàn)代碼。舉個(gè)例子,一個(gè)開(kāi)源項(xiàng)目,要把代碼公布出去,但是代碼中有些比較敏感的部分不想讓別
發(fā)表于 03-12 22:18
嘀聲報(bào)警信號(hào)輸出試驗(yàn)(含C語(yǔ)言源程序代碼)
嘀聲報(bào)警信號(hào)輸出試驗(yàn)(含C語(yǔ)言源程序代碼)
這一課,我們將學(xué)習(xí)如何控制蜂鳴器的聲音輸出,這一課我們只輸出
發(fā)表于 08-09 10:48
?3389次閱讀
一個(gè)按鍵控制的10級(jí)變速跑馬燈試驗(yàn)(含源程序C語(yǔ)言代碼)
一個(gè)按鍵控制的10級(jí)變速跑馬燈試驗(yàn)(含源程序C語(yǔ)言代碼)
在本課中,我們要用一個(gè)按鍵來(lái)實(shí)現(xiàn)
發(fā)表于 08-09 23:20
?3378次閱讀
卡爾曼濾波簡(jiǎn)介及其實(shí)現(xiàn)(附C代碼)
卡爾曼濾波算法介紹,公式實(shí)現(xiàn),后面附有公式的實(shí)現(xiàn)代碼。封裝函數(shù)。
發(fā)表于 12-17 17:22
?40次下載
DSP編程技巧之鏈接匯編代碼與C_C++代碼
在DSP的開(kāi)發(fā)中,常用的算法都可以用C/C++代碼來(lái)高效實(shí)現(xiàn)。但是對(duì)一些特殊寄存器的讀寫(xiě),例如某些CPU寄存器的讀寫(xiě),因?yàn)?b class='flag-5'>C/
發(fā)表于 10-18 09:47
?7次下載
基于單片機(jī)AT89C52和DS1302的溫度時(shí)間顯示方案含源代碼程序
電子發(fā)燒友網(wǎng)站提供《基于單片機(jī)AT89C52和DS1302的溫度時(shí)間顯示方案含源代碼程序.zip》資料免費(fèi)下載
發(fā)表于 01-02 11:34
?17次下載
使用C語(yǔ)言實(shí)現(xiàn)靜態(tài)網(wǎng)頁(yè)的代碼免費(fèi)下載
本文檔的主要內(nèi)容詳細(xì)介紹的是使用C語(yǔ)言實(shí)現(xiàn)靜態(tài)網(wǎng)頁(yè)的代碼免費(fèi)下載。
發(fā)表于 11-22 16:20
?2次下載
UDP及TCP通信的程序設(shè)計(jì)和源代碼免費(fèi)下載
本文檔的主要內(nèi)容詳細(xì)介紹的是UDP及TCP通信的程序設(shè)計(jì)和源代碼免費(fèi)下載。
發(fā)表于 01-08 15:12
?37次下載
評(píng)論