C语言写了一个socket server端,适合windows和linux,用GCC编译运行通过
///////////////////////////////////////////////////////////////////////////////
/*
gcc -Wall -o s1 s1.c -lws2_32
*/
///////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#define _WIN32_WINNT 0x501
#define PORT 4000
#define IP_ADDRESS "127.0.0.1"
///////////////////////////////////////////////////////////////////////////////
// SK
#ifdef _WIN32_WINNT
#include <ws2tcpip.h>
#include <winsock2.h>
WSADATA Ws;
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <netdb.h>
#endif
///////////////////////////////////////////////////////////////////////////////
// SK
void connect_inet_socket( int *psockfd, const char* host, int port );
#ifdef _WIN32_WINNT
void connect_windows_socket( int *psockfd, const char* pathname );
#else
void connect_unix_socket( int *psockfd, const char* pathname );
#endif
void writebuffer_socket( int sockfd, const void *data, int len );
void readbuffer_socket( int sockfd, void *data, int len );
void shutdown_socket( int sockfd );
///////////////////////////////////////////////////////////////////////////////
// SK
/* Access to sockets needs to be done with a wrapper function 'connect_socket'
and it is substituted by 'connect_windows_socket' or by 'connect_unix_socket'
( depends on a state of the macro _WIN32 ) during preprocessing phase of
the compilation.
For portability 'connect_windows_socket' and 'connect_unix_socket' shouldn't
be used directly and the wrapper function 'connect_socket' must be used instead.
*/
#ifdef _WIN32_WINNT
#define connect_socket connect_windows_socket
#else
#define connect_socket connect_unix_socket
#endif
int socket_desc;
struct sockaddr_in server;
///////////////////////////////////////////////////////////////////////////////
/* Opens an internet socket.
Note that fortran passes an extra argument for the string length,
but this is ignored here for C compatibility.
Args:
psockfd: The id of the socket that will be created.
port: The port number for the socket to be created. Low numbers are
often reserved for important channels, so use of numbers of 4
or more digits is recommended.
host: The name of the host server.
*/
void connect_inet_socket( int *psockfd, const char* host, int port )
{
int sockfd, ai_err;
// creates an internet socket
// fetches information on the host
struct addrinfo hints, *res;
char service[256];
memset(&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_PASSIVE;
//sprintf(service, "%d", port); // convert the port number to a string
//ai_err = getaddrinfo(host, service, &hints, &res);
//if (ai_err!=0) {
// printf("Error code: %i\n",ai_err);
// perror("Error fetching host data. Wrong host name?");
// exit(-1);
//}
// creates socket
//sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
sockfd = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
if (sockfd < 0) {
perror("Error opening socket");
exit(-1);
}
else
{
printf("creates socket:%d\n", sockfd);
}
// makes connection
if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0) {
perror("Error opening INET socket: wrong port or server unreachable");
exit(-1);
}
freeaddrinfo(res);
*psockfd = sockfd;
}
///////////////////////////////////////////////////////////////////////////////
// SK
/* Opens a socket.
Note that fortran passes an extra argument for the string length,
but this is ignored here for C compatibility.
Args:
psockfd: The id of the socket that will be created.
pathname: The name of the file to use for sun_path.
*/
#ifdef _WIN32_WINNT
void connect_windows_socket( int *psockfd, const char* pathname )
{
// Required functionality for Windows
// ...
}
#else
void connect_unix_socket( int *psockfd, const char* pathname )
{
// Required functionality for Unix
int sockfd, ai_err;
struct sockaddr_in serv_addr;
printf("Connecting to :%s:\n",pathname);
// fills up details of the socket addres
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sun_family = AF_UNIX;
/* Beware of buffer over runs
UNIX Network Programming by Richard Stevens mentions
that the use of sizeof() is ok, but see
http://mail-index.netbsd.org/tech-net/2006/10/11/0008.html
*/
if ((int)strlen(pathname)> sizeof(serv_addr.sun_path)) {
perror("Error opening UNIX socket: pathname too long\n");
exit(-1);
} else {
strcpy(serv_addr.sun_path, pathname);
}
// creates a unix socket
// creates the socket
sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
// connects
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
perror("Error opening UNIX socket: path unavailable, or already existing");
exit(-1);
}
*psockfd = sockfd;
}
#endif
///////////////////////////////////////////////////////////////////////////////
/* Writes to a socket.
Args:
sockfd: The id of the socket that will be written to.
data: The data to be written to the socket.
len: The length of the data in bytes.
*/
void writebuffer_socket( int sockfd, const void *data, int len )
{
int n;
n = write(sockfd, (char *) data, len);
if (n < 0) {
perror("Error writing to socket: server has quit or connection broke");
exit(-1);
}
}
///////////////////////////////////////////////////////////////////////////////
/* Reads from a socket.
Args:
sockfd: The id of the socket that will be read from.
data: The storage array for data read from the socket.
len: The length of the data in bytes.
*/
void readbuffer_socket( int sockfd, void *data, int len )
{
int n, nr;
char *pdata;
pdata = (char *) data;
n = nr = read(sockfd, pdata, len);
while (nr > 0 && n < len) {
nr = read(sockfd, &(pdata[n]), len - n);
n += nr;
}
if (n == 0) {
perror("Error reading from socket: server has quit or connection broke");
exit(-1);
}
}
///////////////////////////////////////////////////////////////////////////////
/* Shuts down the socket.
*/
void shutdown_socket( int sockfd )
{
shutdown( sockfd, 2 );
close( sockfd );
}
DWORD WINAPI ClientThread(LPVOID lpParameter)
{
SOCKET CientSocket = (SOCKET)lpParameter;
int Ret = 0;
char RecvBuffer[1024];
char message[] = "Hello Master HaKu!";
while ( 1 )
{
memset(RecvBuffer, 0x00, sizeof(RecvBuffer));
Ret = recv(CientSocket, RecvBuffer, 1024, 0);
if ( Ret == 0 || Ret == SOCKET_ERROR )
{
printf("客户端退出!\n");
break;
}
printf("接收到客户信息为%s\n", RecvBuffer);
//Ret = send(CientSocket, "hello world", (int)strlen("hello world"), 0);
//Ret = write(CientSocket, "hello world", sizeof("hello world"));
//write(CientSocket, message, sizeof(message));
send(CientSocket, "hello world", strlen("hello world"), 0);
//if ( Ret == 0 || Ret == SOCKET_ERROR )
//{
printf("返回给客户端%s\n", message);
// break;
//}
}
return 0;
}
int main(void)
{
int *socket_desc;
SOCKET ServerSocket, ClientSocket;
struct sockaddr_in LocalAddr, ClientAddr;
int Ret = 0;
int AddrLen = 0;
HANDLE hThread = NULL;
char SendBuffer[MAX_PATH];
char message[30] = "Hello Master HaKu!";
#ifdef _WIN32_WINNT
//Init Windows Socket
if ( WSAStartup(MAKEWORD(2,2), &Ws) != 0 )
{
printf("Init Windows Socket Failed");
return -1;
}
#endif
//connect_inet_socket(socket_desc, "http://blog.csdn.net", 80);
//Create socket
ServerSocket = socket(AF_INET , SOCK_STREAM , IPPROTO_TCP);
if (socket_desc == -1)
{
printf("Could not create socket");
}
LocalAddr.sin_family = AF_INET;
LocalAddr.sin_addr.s_addr = inet_addr(IP_ADDRESS);
LocalAddr.sin_port = htons(PORT);
memset(LocalAddr.sin_zero, 0x00, 8);
//Bind Socket
Ret = bind(ServerSocket, (struct sockaddr*)&LocalAddr, sizeof(LocalAddr));
if ( Ret != 0 )
{
printf("Bind Socket Failed");
//return -1;
}
//listen
Ret = listen(ServerSocket, 10);
if ( Ret != 0 )
{
printf("listen Socket Failed");
//return -1;
}
printf("服务端已经启动\n");
while ( 1 )
{
AddrLen = sizeof(ClientAddr);
ClientSocket = accept(ServerSocket, (struct sockaddr*)&ClientAddr, &AddrLen);
if ( ClientSocket == INVALID_SOCKET )
{
printf("Accept Failed");
break;
}
//write(ClientSocket, message, sizeof(message));
send(ClientSocket, message, strlen(message), 0);
printf("客户端连接\n");
hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)ClientSocket, 0, NULL);
if ( hThread == NULL )
{
printf("Create Thread Failed!");
break;
}
CloseHandle(hThread);
}
closesocket(ServerSocket);
closesocket(ClientSocket);
WSACleanup();
return 0;
}
C语言写了一个socket server端,适合windows和linux,用GCC编译运行通过的更多相关文章
- C语言写了一个socket client端,适合windows和linux,用GCC编译运行通过
////////////////////////////////////////////////////////////////////////////////* gcc -Wall -o c1 c1 ...
- 用select (多路复用)模拟一个 socket server
需求:用select (多路复用)模拟一个 socket server.可以接收多并发. 1. 一开始是检测自己,如果我有活动了,就说明有客户端要连我了. #用select去模拟socket,实现单线 ...
- 第一个socket服务端程序
第一个socket服务端程序 #include <stdio.h> #include <stdlib.h> #include <string.h> #include ...
- 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧拿出来拍啊
花10天时间用C语言做了个小站 http://tieba.yunxunmi.com/index.html 简称: 云贴吧 不好意思啊,我上周到今天不到10天时间,用纯C语言写了一个小站!想拍砖的就赶紧 ...
- 用Racket语言写了一个万花筒的程序
用Racket语言写了一个万花筒的程序 来源:https://blog.csdn.net/chinazhangyong/article/details/79362394 https://github. ...
- 在Linux使用GCC编译C语言共享库
在Linux使用GCC编译C语言共享库 对任何程序员来说库都是必不可少的.所谓的库是指已经编译好的供你使用的代码.它们常常提供一些通用功能,例如链表和二叉树可以用来保存任何数据,或者是一个特定的功能例 ...
- 用select模拟一个socket server成型版
1.你往output里面放什么,下次循环就出什么. 2. 1.服务器端:实现了收和发的分开进行 import select,socket,queue server=socket.socket() s ...
- 用select模拟一个socket server
1, 必须在非阻塞模式下,才能实现IO的多路复用,否则一个卡住就都卡住了.(单线程下的多路复用) 先检测自己,现在没有客户端连进来,所以会卡住. # 用select去模拟socket,实现单线程下的多 ...
- 使用PHP创建一个socket服务端
与常规web开发不同,使用socket开发可以摆脱http的限制.可自定义协议,使用长连接.PHP代码常驻内存等.学习资料来源于workerman官方视频与文档. 通常创建一个socket服务包括这几 ...
随机推荐
- Amaze UI 云适配
Amaze UI 云适配 陈本峰 一中,中科大 香港科大
- linux systemctl 常用用法简介
主要介绍systemctl的几个功能如下: 1.查看某个服务的状态 2.关闭某个服务 3.开启某个服务 4.设置某个为开机自启动 5.关闭某个服务为开机不启动 6.查看所有开启启动的服务 1.查看某个 ...
- Scala深入浅出实战经典:29,Case class和Case object代码实战解析
今天学习了王家林老师scala讲座的第29讲,case class和case object的应用实战.做下记录. 信息来源于 DT大数据梦工厂微信公众账号:DT_Spark 关注微信账号,获取更多关于 ...
- java的并发和多线程
本文主要讲解Java并发相关的内容,包括锁.信号量.堵塞队列.线程池等主要内容. 并发的优点和缺点 在讲述怎么利用多线程的情况下,我们先看一下采用多线程并发的优缺点. 优点 提高资源利用率 如读取一个 ...
- HDU 2476 区间DP-刷字符问题-思维考察
区间DP-刷字符问题-思维考察 翻译了一下这个题,一看还是有点难以入手,标明了是区间DP问题,但是如何DP呢 来捋一捋思路吧 dp[i][j]肯定是从i刷到j所要的次数但是它的i和j是s1串还是s2串 ...
- js-选项卡套选项卡
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- Python自动化开发 - 函数式编程
本节内容 一.函数式编程 二.高阶函数 1.变量可以指向函数 2.函数名也是变量 3.传入函数 三.返回函数 1.函数作为返回值 2.闭包特性 一.函数式编程 函数是Python内建支持的一种封装,我 ...
- B样条基函数的定义及系数的意义
原文链接:http://blog.csdn.net/tuqu/article/details/5177405 贝塞尔基函数用作权重.B-样条基函数也一样:但更复杂.但是它有两条贝塞尔基函数所没有的特性 ...
- Aspose Word.Dll库自带的bug导致The document appears to be corrupted and cannot be loaded 问题处理。
问题的详细描述: C#在开发过程中使用Aspose.word.dll库去实现word套打功能.但是,最近客户反映出现了一个问题,在打印文档的时候,系统报错.经过定位分析发现是Aspose.word.d ...
- Linux之IRQ domain
概述 Linux使用IRQ domain来描述一个中断控制器(IRQ Controller)所管理的中断源.换句话说,每个中断控制器都有自己的domain.我们可以将IRQ Domain看作是IRQ ...